JavaScript Nodejs: How to avoid nested .then() when using async/await node.js avoid nested callbacks,node js nested callbacks

Following is what I'm trying to do this in nodejs. The Rest API takes a city name as an input. I am trying to get the latitude and longitude using the geocode API for the input city. then, using the latitude and longitude, I am trying to get a list of closest cities using another API. then, for all those cities, I am getting the weather report, then for those cities, I am getting whether there is water and I am returning this back as a JSON.

As you can see, there is a lot of then and the goal of this exercise is to avoid nested callbacks.

I am using async/await which is supposed to have eliminated the nested then functions. But I don't see another way of doing this. The complete code snippet is below. The ugly part I am trying to fix is requester.makeRequest()

Following is just a snippet of the necessary code and not the complete working code. Any help on how to untangle this would be greatly appreciated.

app.get('/search', function(req, res, next) {
  const requester = {
      lastRequest: new Date(),
      makeRequest: async function(url) {
        const response = await fetch(url);
        const json = await response.json();
        return json;
      }
  };

requester.makeRequest(geocode_url +`?locate=${req.query.q}&json=1`
    + geocode_token)
  .then(function(city){
    var final_result = []
    var lat = city.latt;
    var long = city.longt;
    // request to get list of cities closer to that location,
    //takes latitude and longitude as parameters
    requester.makeRequest(metaweather_url + '?lattlong='
     + lat + ',' + long)
    .then(function(closer_cities) {
      var cities_len = closer_cities.length
      for(i = 0; i < closer_cities.length; i++) {
        woeid = closer_cities[i].woeid
        //request to get weather using woeid parameter
        requester.makeRequest(woeid_url + woeid)
        .then(function(weather) {
          var lattlong = weather.latt_long;
          requester.makeRequest(onwater_url+ lattlong +
          '?access_token=' + water_access_token)
          .then(function(onwater) {
            var temp = Object.assign(weather, onwater)
            final_result.push(temp)
            if (final_result.length == cities_len) {
              res.status(200).json({error: false,
                data: {message: final_result}})
            }
          })
        })
       }
      })
    })
  })
Answer:1

for this line : requester.makeRequest ... .then(function(city){

replace .then(function(city){ with var city = await requester.makeRequest , city will have the fulfilled value of the promise, do this for the rest of thens :

( keep in mind that await is only used inside an async function, you can use an iife )

(async () => {


  var city = await requester.makeRequest(`${geocode_url}?locate=${req.query.q}&json=1${geocode_token}`);

  var final_result = []
  var lat = city.latt;
  var long = city.longt;
  // request to get list of cities closer to that location,
  //takes latitude and longitude as parameters
  var closer_cities = await requester.makeRequest(`${metaweather_url}?lattlong=${lat},${long}`);

  var cities_len = closer_cities.length;

  for (i = 0; i < closer_cities.length; i++) {
    woeid = closer_cities[i].woeid
    //request to get weather using woeid parameter
    var weather = await requester.makeRequest(woeid_url + woeid);

    var lattlong = weather.latt_long;
    var onwater = await requester.makeRequest(`${onwater_url}${lattlong}?access_token=${water_access_token}`);

    var temp = Object.assign(weather, onwater)
    final_result.push(temp)
    if (final_result.length == cities_len) {
      res.status(200).json({
        error: false,
        data: {
          message: final_result
        }
      })
    }
  }

})();
Answer:2

I would say you still need one then

requester.makeRequest(geocode_url +`?locate=${req.query.q}&json=1`
    + geocode_token)
  .then(async function(city){
    var final_result = []
    var lat = city.latt;
    var long = city.longt;
    // request to get list of cities closer to that location,
    //takes latitude and longitude as parameters
    closer_cities = await requester.makeRequest(metaweather_url + '?lattlong='+ lat + ',' + long);
    var cities_len = closer_cities.length;
    for(i = 0; i < closer_cities.length; i++) {
      woeid = closer_cities[i].woeid
      //request to get weather using woeid parameter
      weather = await requester.makeRequest(woeid_url + woeid)
      var lattlong = weather.latt_long;
      onwater = await awaitrequester.makeRequest(onwater_url+ lattlong + '?access_token=' + water_access_token)
      var temp = Object.assign(weather, onwater)
      final_result.push(temp)
      if (final_result.length == cities_len) {
        res.status(200).json({error: false, data: {message: final_result}})
      }
    }
  })

Edit: I don't really think my answer is relevant for your problem sorry

Answer:3

then is misused in the first place because it results in callback hell. Promises are callback-based but they support chaining which is supposed to eliminate nested callbacks.

It should be:

  requester.makeRequest(geocode_url +`?locate=${req.query.q}&json=1` + geocode_token)
  .then(function(city){
    var final_result = []
    var lat = city.latt;
    var long = city.longt;

    return requester.makeRequest(metaweather_url + '?lattlong='
     + lat + ',' + long)
  })
  .then(function(closer_cities) {
     ...
  });

If there's a promise inside then, it should be returned. This way there's no more than a single level of callback nesting.

await is syntactic sugar for then, and rejections should be handled as well:

app.get('/search', function(req, res, next) {
  try {
    ...
    const city = await requester.makeRequest(geocode_url +`?locate=${req.query.q}&json=1`
      + geocode_token);
    var final_result = []
    var lat = city.latt;
    var long = city.longt;

    const closer_cities = await requester.makeRequest(metaweather_url + '?lattlong='
         + lat + ',' + long);
    ...
  } catch (err) {
    next(err)
  }
});
Answer:4

I want to hide the images which are broken in the code below. The issue is that i not having access to the html code as it is getting generated dynamically so need to do it in JS only. I am newbee in ...

I want to hide the images which are broken in the code below. The issue is that i not having access to the html code as it is getting generated dynamically so need to do it in JS only. I am newbee in ...

  1. hide broken images
  2. hide broken images javascript
  3. hide broken images wordpress
  4. css hide broken images
  5. jquery hide broken images
  6. html hide broken images
  7. angularjs hide broken images

Let me show you an example of what I want to accomplish: Say I want to call a functions sub function's sub function's sub function (and so on, lets say for 50+ sub functions), like: foo(arg).bar(...

Let me show you an example of what I want to accomplish: Say I want to call a functions sub function's sub function's sub function (and so on, lets say for 50+ sub functions), like: foo(arg).bar(...

I have a <CountDown/> component that I'd like to hold it's own logic so it can be reusable else where in the app. I'm struggling to reason how could I setState to show:true on a sibling ...

I have a <CountDown/> component that I'd like to hold it's own logic so it can be reusable else where in the app. I'm struggling to reason how could I setState to show:true on a sibling ...

  1. react state from props
  2. react state from child to parent
  3. react state from parent
  4. react state from another component
  5. react state from child
  6. react state from function
  7. react state from localstorage
  8. react state from context
  9. react state in functional component
  10. react/state-in-constructor
  11. react state in constructor or not
  12. react/state-in-constructor eslint
  13. react state in component
  14. react state in class
  15. react state in render
  16. react state in typescript
  17. react state in class component
  18. react state in const
  19. react state in child component
  20. react state for checkbox

I can save all data varchar/text element from my form, but I can't save my path image. Whats is wrong with my code? Lets see my create.blade.php I can save value of var deadline but I can't save ...

I can save all data varchar/text element from my form, but I can't save my path image. Whats is wrong with my code? Lets see my create.blade.php I can save value of var deadline but I can't save ...

  1. save path image android
  2. save path image
  3. save image path in database codeigniter
  4. save image path in database c#
  5. save image path in database php
  6. save image path in sqlite android
  7. save image path in database laravel
  8. save image path in database
  9. save image path in database asp.net c#
  10. save image path in database asp.net c# mvc
  11. save image path in mysql using php
  12. save image path in database c# windows application
  13. save image path in database java
  14. save image path c#
  15. save image path python
  16. save image path in database mvc
  17. save image path in database c# mvc
  18. save image path in mysql
  19. save image path in sharedpreferences
  20. save image path sql server