James
James

Reputation: 1475

In node Express project, how to access a javascript library from within a controller within an MVC framework

I have a controllers folder in my node Express project. I have installed Axios via npm and required it in my app.js file. I need to access Axios from within my controller. I can do so by requiring it again at the top of my controller file but I was wondering if this is the correct way of doing so. In my app.js file after requiring axios I have have tried

  app.use(axios)

and

    app.use((req , res , next){
res.locals.axios = axios;
next()
)

But neither of these functions work. So I am back to requiring Axios from the controller, which does work but doesnt seem like the best method. Below is my controller

const axios = require('axios');

exports.home = (req , res) => {
    res.render('index' , {
        title : 'Check the weather in your town'
    })
}

exports.getWeather = function (req, res) {
    let city = req.body.city;
    console.log(city)
    axios.all([
      axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-03'),
      axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-02')
    ]).then(axios.spread((response1, response2) => {
      console.log(response1.data.url);
      console.log(response2.data.url);
    })).catch(error => {
      console.log(error);
    });
    res.redirect('/')
  }

Upvotes: 0

Views: 50

Answers (2)

Noe Vega
Noe Vega

Reputation: 41

I agree with @MindlessRouse answer. If you really want to, create a function, passing axios as an argument then return the middleware function using axios:

exports.getWeather = function(axios){
    return function (req, res) {
        let city = req.body.city;
        console.log(city)
        axios.all([
          axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-03'),
          axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-02')
        ]).then(axios.spread((response1, response2) => {
          console.log(response1.data.url);
          console.log(response2.data.url);
        })).catch(error => {
          console.log(error);
        });
        res.redirect('/')
    };
}

You can then mount the function in express app like this:

   const controller = require('controller.js');
   ...
   app.use( controller.getWeather(axios) );

Upvotes: 0

MindlessRouse
MindlessRouse

Reputation: 187

I feel you are over thinking this.

Node's require does magic and using caching to help reduce overhead for requiring modules into files. Don't worry about requiring the same module in a few different files.

Even if you could get this to work you have to consider a few other things.

  • How would you test it? There are loads of testing frameworks that help you override requires to help with unit testing. You would likely have to homebrew something in case 1.

  • Are all of your endpoints going to use axios? What if as you grow you have other endpoints that dont need it. Now you would be forcing it in.

  • Where does it end? If there was another require would you also pass that through app.js?

  • Having the require where you use it make it more maintainable. When you come back and look at this in two months will you be confused about where axios is coming from?

tl;dr: Requiring Axios from the controller is the best method

Upvotes: 2

Related Questions