Executing Multiple Sequelize JS model query methods with Promises - Node

Danial picture Danial · Jan 22, 2018 · Viewed 8k times · Source

I am having a problem retrieving data from database using sequelize js. I am new to NODEJS. I don't know if Promise and Promise.all are built in functions So i install and require npm promise in my code too. Below is my code.

var Promise = require('promise');

var user_profile = new Promise(function(resolve, reject) {
    db.user_profile.findOne({
        where: {
            profile_id: new_profile_id
        }
    }).then(user => {
        console.log('Summary Result User found.');
        resolve(user);
    });
});

var all_reports = new Promise(function(resolve, reject) {
    db.report.all().then(reports => {
        console.log('Summary Result Reports found.');
        resolve(reports);
    });
});

var report_details = new Promise(function(resolve, reject) {
    db.report_detail.findAll({
        where: {
            profile_id: new_profile_id
        }
    }).then(report_details => {
        console.log('Summary Result Report Details found');
        resolve(report_details);
    });
});

var all_promises = Promise.all([user_profile, all_reports, report_details]).then(function(data) {
    console.log('**********COMPLETE RESULT****************');
    console.log(data);
}).catch(err => {
    console.log('**********ERROR RESULT****************');
    console.log(err);
});

I want to get the data of all three queries. When i run them individually I get the data but when i run them in Promise.all I only get user_profile data and other two remain undefined I have also tried nested these queries with .then but result is still same I only get one query data other two remain undefined

with then chainging

var results = [];
var new_profile_id = req.params.profile_id;
console.log(new_profile_id);
db.user_profile.findOne({
    where: {
        profile_id: new_profile_id
    }
}).then(user => {
    console.log('Summary Result User found.');
    results.push(user.dataValues);
    return user;
}).then(user => {
    db.report.all().then(reports => {
        console.log('Summary Result Reports found.');
        results.push(reports.dataValues);
        return reports
    });
}).then(reports => {
    db.report_detail.findAll({
        where: {
            profile_id: new_profile_id
        }
    }).then(report_details => {
        console.log('Summary Result Report Details found');
        results.push(report_details.dataValues);
        console.log('**********COMPLETE RESULT****************');
        console.log(results);
        console.log('**********COMPLETE RESULT****************');
        return report_details;
    });
});

can someone please help me in this concept what i am doing wrong. Thanks

Answer

Eye picture Eye · Jan 22, 2018

The latest version of Node.js already supports Promise natively, so does Sequelize. This means no need to require promise separately.

The following code is based on yours.

const user_profile = db.user_profile.findOne({
    where: {
        profile_id: new_profile_id
    }
});

const all_reports = db.report.all();

const report_details = db.report_detail.findAll({
    where: {
        profile_id: new_profile_id
    }
});

Promise
    .all([user_profile, all_reports, report_details])
    .then(responses => {
        console.log('**********COMPLETE RESULTS****************');
        console.log(responses[0]); // user profile
        console.log(responses[1]); // all reports
        console.log(responses[2]); // report details
    })
    .catch(err => {
        console.log('**********ERROR RESULT****************');
        console.log(err);
    });

Notice that there is no need to wrap Sequelize calls with Promise becasue Sequelize already returns promises. This way you only need to have one catch in the last Promise.all() which you were missing in all calls. What this means is that if any calls were to fail, a corresponding resolve would never be called. This, in turn, means that the last Promise.all() would also never be called. This is why it is good to handle all errors at the end once, unless there are some custom error handling requirements.