0

I am trying to iterate through a range of dates to return the top song for each date. So I have a for loop. Within this for loop a function is called to look through my database for the top song. Therefore I wrapped it in a promise in order that it would hold up the for loop, but this approach does not seem to work either. Can someone explain a better approach to solve this issue.

app.post('/getDate', function (req, res) {
      this.tracks = [];
      let until = new Date(req.body.dateToOutput);
      for (var d = new Date(req.body.dateFromOutput); d <= until; d.setDate(d.getDate() + 1)) {
            date = d.toLocaleDateString('en-US', { timeZone: 'UTC' });
            console.log('date', date);
            new Promise(function (resolve, reject) {
                  getDate(date).then(() => {
                        resolve();
                  })
            });
      }
      console.log(this.tracks);
});
function getDate(date) {
      return new Promise(function (resolve, reject) {
            Track.find({ Date: date }, function (err, track) {
                  if (!err) {
                        console.log(track);
                        this.tracks.push(track);
                        resolve();
                  }
                  else {
                        reject();
                  }
            }).sort({ Streams: -1 }).limit(1);
      });
}
3
  • I think your question has already been answered, check this: stackoverflow.com/questions/40328932/… Commented Apr 15, 2020 at 1:54
  • Also you are using a very strange for loop which can probably breaks or throw a bunch of errors, why not using numeric values?, i think my answer will not works if you don't repair the loop. Commented Apr 15, 2020 at 2:39
  • Ahhh another thing i forgot, in your getDate function you have .sort({Streams: -1}).limit(1), which will never be reflected in your code, because is done after the Track.find method is executed, but the return of your Track.find method i suspect is always undefined, and if isn't undefined, you are applyng it to something that will not be returned in the promise, so you are making operations that will not being reflected in your promise, is something like create a variable and not use it. Commented Apr 15, 2020 at 2:49

1 Answer 1

1

I think the promise is not being executed, and also i think you are pointing to an undefined object in your getDate function, and the for loop doesn't waits to a promise to be solved or rejected. see this:

new Promise(function (resolve, reject) {
    getDate(date).then(() => {
        resolve();
    })
});

you are creating a new promise but you never execute this promise.

also in the function getDate you are pointing to an object that doesn't exists in his context:

this.tracks.push(track);

This will throw you some errors, because this.tracks is not part of getDate function is part of an anonymous function which is called by the app.post method.

so instead of pushing something in this.tracks directly, you must return the track itself:

if (!err) {
    console.log(track);
    resolve(track);
}

then you should use async - await to obligate the loop for make a pause at the promise until this being resolved or rejected, so your anonymous function, should be now an async anonymous function in order to use await, also you don't need a wrapper of a promise inside another promise, i mean you don't need this:

new Promise(function (resolve, reject) {
    getDate(date).then(() => {
        resolve();
    })
});

You only need this:

getDate(date).then(() => {
   resolve();
})

because the getDate() function returns a promise itself.

So this is how your code looks after making all these changes:

const response = app.post('/getDate', async function (req, res) {
      this.tracks = [];

      let until = new Date(req.body.dateToOutput);
      for (var d = new Date(req.body.dateFromOutput); d <= until; d.setDate(d.getDate() + 1)) {
            date = d.toLocaleDateString('en-US', { timeZone: 'UTC' });
            console.log('date', date);
            const ctrack = await getDate(date);
            this.tracks.push(ctrack);
      }

      console.log(this.tracks);
      return this.tracks;
});

function getDate(date) {
      return new Promise(function (resolve, reject) {
            Track.find({ Date: date }, function (err, track) {
                  if (!err) {
                        console.log(track);
                        resolve(track);
                  }
                  else {
                        reject();
                  }
            }).sort({ Streams: -1 }).limit(1);
      });
}

And now that you have the response as a promise, because an async function returns a promise... you can then and catch it and use the response:

response.then(trackList =>{
   console.log(trackList);
}).catch(()=>{
   console.error("something went wrong...!");
})
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.