Question

I'm developing a project with angular frontend and a restfull backend developed in nodejs. This project uses an existing MySQL database. I use sequelizejs orm to connect node with mysql.

In database have 2 entities: user and project. A project have many users (named as workers)

Project.findAll().success(function(projects) {

     var array=[];
     projects.forEach(function(project) {

         project.getWorkers().success(function(users) {
              project.workers=users;
              console.log('a');
         });
         console.log('b');
         array.push(project);

     });

     console.log('c');
         res.json(array);
     });

Sequelize works fine. It returns me all projects and getWorkers returns the correct users of this project.

What is the problem? The problem is asincronously calls, getWorkers is called after response sended. This is incorrect. I need to add workers in every project before the result send. The console.log says: b b b c a a a a a a a a ("c" is the json response called before "a" getWorkers. The correct way is: b a a a b a a a a a b a c

Was it helpful?

Solution

You have two options here: you can either modify your existing code slightly to only return once all getWorkers calls have succeeded, or you can use eager loading to fetch projects and workers in one go:

Option 1

Project.findAll().success(function(projects) {

    var array =[],
        done = _.after(projects.length, function () {
            res.json(array);
        });

    projects.forEach(function (project) {
         project.getWorkers().success(function(users) {
              project.workers = users;
              done();
         });
         array.push(project);
    });
});

_.donecreates a function that invokes res.json after it has been called projects.length times. If you don't already have underscore/lodash in your project, you can use Sequelize.Utils._.after.

Option 2

Project.findAll({
    include: [
        { model: User, as: 'Workers' }
   ]
}).success(function (projects) {
    // project.workers is already populated here
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top