BayLife BayLife - 1 month ago 22
Javascript Question

Iterate over array in async promise

I´m working with node/ express, mysql and bluebird.

I´m using Promises to make an async database call, which is working so far. But now I want to iterate over the result (array) and call a function for calculation purpose.

My Code is separated into a Controller class, which handles the

get/ post
request. In the middle a service class for business logic, which talks to a database class which queries in the database.

For now I will just show my service class, because everything else is working perfectly, I just don´t know how to run over the result array and call function, which returns a daterange.

'use strict';

var departmentDatabase = require('../database/department');
var moment = require('moment');

class DepartmentService {
constructor() {
}

getVacation(departmentID) {
return departmentDatabase.getVacation(departmentID).then(function (result) {

//Without promises I did this, which worked.
//for(var i = 0; result.length > i; i++){
// var dateRange = this.getDateRange(new Date(result[i].dateFrom), new Date(result[i].dateTo));
//console.log(dateRange);
//}
return result;

})

//If I do it static, the dateRange function is successfully called
//But here I don´t know how to do it for the entire array.
//Also I don´t know, how to correctly get the result dateRange()
.then(result => this.dateRange(result[0].dateFrom, result[0].dateTo))
//.then() Here I would need an array of all dateRanges
.catch(function (err) {
console.log(err);
});
}

getDateRange(startDate, stopDate) {
console.log("inDateRange");
console.log(startDate + stopDate);

var dateArray = [];
var currentDate = moment(startDate);
while (currentDate <= stopDate) {
dateArray.push(moment(currentDate).format('YYYY-MM-DD'))
currentDate = moment(currentDate).add(1, 'days');
}

return dateArray;
}
}

module.exports = new DepartmentService();


Hope someone can give me an example on how to do it right.

Answer

In your new code, you're only handling the first result. You probably want map:

.then(result => result.map(entry => this.dateRange(entry.dateFrom, entry.dateTo)))

So in context with the old code removed:

getVacation(departmentID) {
    return departmentDatabase.getVacation(departmentID)
    .then(result => result.map(entry => this.dateRange(entry.dateFrom, entry.dateTo)))
    .catch(function (err) {
        console.log(err);
        // WARNING - This `catch` handler converts the failure to a
        //           resolution with the value `undefined`!
    });
}

Note the warning in the above. If you want to propagate the error, you need to do that explicitly:

.catch(err => {
    // ...do something with it...
    // If you want to propagate it:
    return Promise.reject(err);
    // Or you can do:
    // throw err;
});