Search code examples
javascriptnode.jsasync-awaitpromisees6-promise

How do I return value from promise in javascript?


I am fairly new to working with promises and now I got stuck. I read a few articles and SO posts, but I can't get my head around it.

I have a simple API that returns an array of people and some properties like firstname, lastname and d.o.b. I want to check for birthays within the next 10 days. Now I am stuck with the function returning a promise. I want the API to return an array with an array for people and an arry for nextBirthdays.

How do I resolve the promise?

( I know the part with calculating the dates is not the most elegant way to do it )

router.get('/', async(req, res) => {

    try {
        const contacts = await Contact.find()

        // Returns promise, but want array
        const nextBirthdays = getNextBirthdays(contacts)

        var promise = Promise.resolve(nextBirthdays);

        promise.then(function(val) {
            console.log(val);
        });

        res.json({ contacts, nextBirthdays })


    } catch (error) {
        res.status(500).json({ message: error.message })
    }
})

async function getNextBirthdays(contacts) {

    contacts.forEach(async(contact) => {

        let daysTillBirthday = await getDaysTillBirthday(contact.dob)

        if (daysTillBirthday < 10 && daysTillBirthday > 0) {
            console.log(`${contact.firstname}'s birthday is in ${daysTillBirthday} days`)
            nextBirthdays.push({
                firstname: contact.firstname,
                days: daysTillBirthday
            })
        }

        // Returns object with next birthdays
        return nextBirthdays

    })
}

async function getDaysTillBirthday(_birthday) {
    const birthday = await birthdayDayOfYear(_birthday)
    const today = await dayOfTheYear()
    const days = birthday - today
    return await days;
}

async function birthdayDayOfYear(date) {
    const now = date;
    const start = new Date(now.getFullYear(), 0, 0);
    const diff = now - start;
    const oneDay = 1000 * 60 * 60 * 24;
    const day = Math.floor(diff / oneDay);
    return await day
}

async function dayOfTheYear() {
    const now = new Date();
    const start = new Date(now.getFullYear(), 0, 0);
    const diff = now - start;
    const oneDay = 1000 * 60 * 60 * 24;
    const day = Math.floor(diff / oneDay);
    return await day
}

Solution

  • Your code should look like this:

    router.get('/', async (req, res) => {
      try {
        const contacts = await Contact.find()
    
        const nextBirthdays = getNextBirthdays(contacts)
    
        res.json({ contacts, nextBirthdays });
      } catch (error) {
        res.status(500).json({ message: error.message })
      }
    })
    
    function getNextBirthdays(contacts) {
      let nextBirthdays = [];
      contacts.forEach(contact => {
    
        let daysTillBirthday = getDaysTillBirthday(contact.dob)
    
        if (daysTillBirthday < 10 && daysTillBirthday > 0) {
          console.log(`${contact.firstname}'s birthday is in ${daysTillBirthday} days`)
          nextBirthdays.push({
            firstname: contact.firstname,
            days: daysTillBirthday
          })
        }
      })
    
      // Returns object with next birthdays
      return nextBirthdays
    }
    
    function getDaysTillBirthday(_birthday) {
      const birthday = birthdayDayOfYear(_birthday);
      const today = dayOfTheYear();
      return birthday - today;
    }
    
    function birthdayDayOfYear(date) {
      const now = date;
      const start = new Date(now.getFullYear(), 0, 0);
      const diff = now - start;
      const oneDay = 1000 * 60 * 60 * 24;
      return Math.floor(diff / oneDay);
    }
    
    function dayOfTheYear() {
      const now = new Date();
      const start = new Date(now.getFullYear(), 0, 0);
      const diff = now - start;
      const oneDay = 1000 * 60 * 60 * 24;
      return Math.floor(diff / oneDay);
    }
    
    module.exports = router;