How can I use my helper in controller

Hi, I’m trying to use my helper (AnalyseAlert) in controller, but it doesn’t work.

Controller:

const AnalyseAlert = use('App/Helpers/AnalyseAlert')

async update ({ params, request }) {
    const disk = await Disk.findOrFail(params.id)

    const data = request.only([
    	'type',
    	'filesystem',
    	'total_space',
      'used_space',
    	'free_space',
    	'percentage_of_use'
    ])

    AnalyseAlert.checkDisk({
      label: disk.label,
      risk: data.percentage_of_use,
      idRegistry: disk.id_registry
    })

    disk.merge(data)

    await disk.save()

    return disk
  }

Helper (AnalyseAlert):

'use strict'

const AlertController = use('App/Controllers/Http/AlertController')

class AnalyseAlert {

  async checkDisk({ data }) {
    const errorType = 'Disk' + data.label
    const description = 'Disco ' + data.label + ' com risco ' + data.risk

    if (data.risk > 60) {
      AlertController.store(data.idRegistry, errorType, description)
    }
  }

}

module.exports = AnalyseAlert

I’m using the insomnia to make requests and the return is “500 Internal Server Error”.

Hello,
You need to implement/register your helper as service provider in Adonis : https://adonisjs.com/docs/4.1/service-providers

or use a simple class and use ‘require’ to import it instead of ‘use’

Best luck

hi , Test this code please

const AlertController = use('App/Controllers/Http/AlertController')

module.exports = new class AnalyseAlert {

 async checkDisk({ data }) {
    const errorType = 'Disk' + data.label
    const description = 'Disco ' + data.label + ' com risco ' + data.risk

    if (data.risk > 60) {
      AlertController.store(data.idRegistry, errorType, description)
    }
  }

}


const AnalyseAlert = use('App/Helpers/AnalyseAlert')


async update ({ params, request }) {
    const disk = await Disk.findOrFail(params.id)

    const data = request.only([
    	'type',
    	'filesystem',
    	'total_space',
      'used_space',
    	'free_space',
    	'percentage_of_use'
    ])

    AnalyseAlert.checkDisk({
      label: disk.label,
      risk: data.percentage_of_use,
      idRegistry: disk.id_registry
    })

    disk.merge(data)

    await disk.save()

    return disk
  }

Hi, @mouradghafiri, I’ll read about service provider to try implement my helper.

And about the use of simple class, I tried to implement using this, but doesn’t work :frowning:

Helper:

const AlertController = use('App/Controllers/Http/AlertController')

class AnalyseAlert {

 async checkDisk(data) {
    const errorType = 'Disk' + data.label
    const description = 'Disco ' + data.label + ' com risco ' + data.risk

    if (data.risk > 60) {
      AlertController.store()
    }
  }

}

And the Controller:

const analyseAlert = require('App/Helpers/AnalyseAlert')

analyse = new analyseAlert();

    analyse.checkDisk({
      label: disk.label,
      risk: data.percentage_of_use,
      idRegistry: disk.id_registry
    })

By the way, I tried add the ‘.js’ in the final of the require, but it doesn’t work too.

Hello, @irdeveloper89, I use your code and this work fine, but in helper I receive this error:

warning: 
  WARNING: Adonis has detected an unhandled promise rejection, which may
  cause undesired behavior in production.
  To stop this warning, use catch() on promises or wrap await
  calls inside try/catch.

TypeError: AlertController.store is not a function
    at AnalyseAlert.checkDisk (/home/guilherme/Documentos/projects/imob-monitor/app/Helpers/AnalyseAlert.js:12:23)
    at DiskController.update (/home/guilherme/Documentos/projects/imob-monitor/app/Controllers/Http/DiskController.js:43:18)

Hey @guiRibas! :wave:

There’s few architecture issues on your code.
To be able to help you I’d like to know what you are exactly trying to externalized?

Hi @romain.lanz!

Firstly thank you for analyse my code!

In my database I have Disk and Alert tables. When I receive the request with data about the Disk I need analyse ‘percentage_of_use’ attribute about that Disk and then if this attribute is bigger then 60 I need create new alert.

So, I think I need analyse ‘percentage_of_use’ inside Helper and then call the AlertController if necessary.

Thank you.

Hello @guiRibas!

Everything is quite fine actually :slight_smile:
Just to give some pointers:

class AnalyseAlert {
  async checkDisk({ data }) {
    ...
  }
}

You can make this checkDisk as static method so you don’t have to create new AnalyseAlert

class AnalyseAlert {
  static async checkDisk({ data }) {
    ...
  }
}

And use like

const AnalyseAlert = use('App/Helpers/AnalyseAlert')

async update ({ params, request }) {
   // No need for new AnalyseAlert() with static methods
  await AnalyseAlert.checkDisk()
}

In checkDisk you are calling methods off from AlertController
For that need to know more about your controllers, but generally it is not good idea to call controller method, better call model method. Like Alert.create()
If you still need to call AlertController.store() then you have to make AlertController first with new

    if (data.risk > 60) {
      const alertController = new AlertController()
       // this is hacky, better use model
      await alertController.store({request: data})
      // Notice that this alertController.store will be 
      // missing everything else from HTTP request
    }
3 Likes

You should never call a controller yourself.

If you want to share logic between multiple space you should externalize the logic in a service.

3 Likes