-1

So i have this little Express.js Application, which accepts a POST-request with a "city" as body. The application processes the call and uses an external service for that. I tried to split up the "Pure" logic from the REST-controller to keep it clean, but somehow when i call the "weather" method, it won't return anything, even if the String, i am passing, is a valid object. My guess is, that there is an issue with an asynchronious call, but i don't see myself in the position, to solve it myself.

RestController.js

  module.exports = (function() {
  var router = require('express').Router()
  var bodyParser = require('body-parser')
  var weather = require('./weather')

  router.use(bodyParser.urlencoded({ extended: true }))
  router.use(bodyParser.json())

//TODO DATABASE CONNECTION

  //REST CONTROLLER
  router.get('/', function(req, res) {
    res.json({response: 'Hello world!'})
  })

  router.post('/weather', function(req, res)  {
    var r = weather(req.body.city)
      res.send(r)
  })

  return router
})();

weather.js

var request = require('request')

module.exports = function(loc) {
  request('http://api.openweathermap.org/data/2.5/weather?q='+loc+'&units=metric&APPID=API_TOKEN', function(err , ires) {
    if(!err) {
      json = JSON.stringify({temp: JSON.parse(ires.body).main.temp, name: JSON.parse(ires.body).name})
      console.log(json)
      return json
    }
    else {
      return err
    }

  })
};

Best regards,

Tim

timschmolka
  • 91
  • 1
  • 4

1 Answers1

1

You should pass a callback to your weather function so you can handle it when it's complete. e.g.

module.exports = function(loc, callback) {
  request('http://api.openweathermap.org/data/2.5/weather?q='+loc+'&units=metric&APPID=API_TOKEN', function(err , ires) {
    if(!err) {
      json = JSON.stringify({temp: JSON.parse(ires.body).main.temp, name: JSON.parse(ires.body).name})
      console.log(json)
      callback(null, json)
    } else {
      callback(err)
    }

  })
};

Then use as follows in your program:

router.post('/weather', function(req, res)  {
    var r = weather(req.body.city, function (e, result) {
        if (e) return res.status(500).send({error: e});
        res.send(result)
    })
})

This is the standard node pattern (there are better ones). Node is non-blocking so it will not wait for your weather request to complete. It will eventually handle it on the event loop once the callback is finally invoked.

chriskelly
  • 7,526
  • 3
  • 32
  • 50