Amiga500
Amiga500

Reputation: 6131

Iterate inside the sequlize result set

I need to iterate over result set from the sequelize result. I have a code that works, but I think something is wrong with it, and it should not be done this way. I have a feeling this is a blocking code. This is the code that works:

 models.Project.findAll({
            where: {ProjectId: projectId}
        })
        .then(function (projects) {
            //Iteration is here
            var projectList = [];
            projects.forEach(function (res) {
                projectList.push(res.dataValues.PartId);
            });
             //then bulk lookup for the result
            models.Customers.findAll({
                where: {'id': {in: [projectList]}}
            }).then(function (customers) {
                reply(customers).code(200);
            }, function (rejectedPromiseError) {
                reply(rejectedPromiseError).code(401);
            });

            //reply(sameparts).code(200);
        }, function (rejectedPromiseError) {
            reply(rejectedPromiseError).code(401);
        });

This iteration parts is done:

projects.forEach(function (res) {
                projectList.push(res.dataValues.PartId);
            });

And then this code is executed as another query:

models.Customers.findAll({
                where: {'id': {in: [projectList]}}
            }).then(function (customers) {
                reply(customers).code(200);
            }, function (rejectedPromiseError) {
                reply(rejectedPromiseError).code(401);
            });

How can I rearange it so it uses Promises?

EDIT (Possible solution): After playing a bit, I believe I have implemented promises.

getAll: function (request, reply) {
    var projectId = request.params.projectid;

    var promises = [];
    var post;

    models.SamePart.findAll({
            where: {ProjectId: projectId}
        })
        .then(function (sameparts) {
            //Iteration is here                
            sameparts.forEach(function (res) {
                promises.push(
                    Promise.all([               
                        models.Parts.findAll({where: {id: res.dataValues.PartId}})
                    ]))
            });
            //Bulk lookup for the parts that were marked as identical

            return Promise.all(promises);
        }).then(function (completepartslist) {
        reply(completepartslist).code(200);
    });

Is this a correct approach? It seems that completepartslist contains many unwanted objects, including Promise stuff. How can I flatten it, so to avoid complex for loops?

Upvotes: 0

Views: 954

Answers (2)

even more simplified

getAll: function (request, reply) {
    models.SamePart.findAll({
        where: { ProjectId: request.params.projectid }
    }).reduce(function (completepartslist, sameparts) {
        return models.Parts.findAll({ where: { id: sameparts.PartId } }).
          then(function(res){
            completepartslist.concat(res)
          });
        }), []);
    }).then(function (completepartslist) {
        reply(completepartslist).code(200);
    });
}

Upvotes: 1

Roamer-1888
Roamer-1888

Reputation: 19288

If you are using .then(), then you are, in all probability, already using promises.

Your original, working code doesn't appear to be blocking.

Your final getAll() looks like it should simplify to :

getAll: function (request, reply) {
    models.SamePart.findAll({
        where: { ProjectId: request.params.projectid }
    }).then(function (sameparts) {
        return Promise.all(sameparts.map(function (res) {
            return models.Parts.findAll({ where: { id: res.dataValues.PartId } });
        }));
    }).then(function (completepartslist) {
        reply(completepartslist).code(200);
    });
}

However, you need to add error handling back in.

Upvotes: 1

Related Questions