2

I am creating an application where a user can have many rooms and each room can have many channels, here is my code when retrieving the rooms and corresponding channels:

getRooms: function (req, res) {
            User.find({id: req.cookies.claver_id}).exec(function (err, result) {
               if (err) {
                  return res.send(400);
               }
               rooms = result[0].rooms;
               if (rooms.length === 1) {//No room defaults to ['']
                   return res.send(400);
               }

               var roomsObj = {};
               var roomsArr = [];//we will place the roomsObj inside the roomsArr

               var chansObj = {};
               var chansArr = [];

               async.each(rooms, function (roomId, cb){
                    roomsObj = {};
                   if (roomId !== '') {
                    Rooms.findOne({id: roomId}).exec(function (err, room){
                        roomName = room.name; 
                        inviteLink = room.inviteLink;
                        roomsObj.name = roomName;
                        roomsObj.id = roomId;
                        roomsObj.inviteLink = inviteLink;

                        var channels = room.channels;
                        async.each(channels, function (channelId, cb) {
                             chansObj = {};
                            Channels.findOne({id: channelId}).exec(function (err, channel){
                            chansObj.name = channel.channelName;
                            chansObj.id = channelId;
                            chansObj.type = channel.channelType;
                            chansArr.push(chansObj);
                            cb();
                       });
                        }, 
                        function (err) {

                        });


                    }); 
                }
                cb(); 

               }, function (err) {
                   roomsObj.channels = chansArr;
                    roomsArr.push(roomsObj);
                   sails.log(roomsArr);

               }); 



            });
        }

It is suppose to return a javascript object with the following structure:

[ { name: "Room Name",
    roomId: "Room Id",
    inviteLink: "Room Invite Link",
    channels: [
                {
                 name: "Channel Name",
                 id: "channel Id"
                 }
               ]
   }

]

But I always get an empty array because async.each(rooms, function (roomId, cb){ }) does not wait for async.each(channels, function (channelId, cb) {}) to complete, so I have empty room object. Please how do I solve this issue ?

Acheme Paul
  • 1,194
  • 15
  • 19

2 Answers2

1

You should call your rooms's callback loop after completing you channels loop.

You should do something like this:

getRooms: function (req, res) {
            User.find({id: req.cookies.claver_id}).exec(function (err, result) {
               if (err) {
                  return res.send(400);
               }
               rooms = result[0].rooms;
               if (rooms.length === 1) {//No room defaults to ['']
                   return res.send(400);
               }

               var roomsObj = {};
               var roomsArr = [];//we will place the roomsObj inside the roomsArr

               var chansObj = {};
               var chansArr = [];

               async.each(rooms, function (roomId, callback1){
                    roomsObj = {};
                   if (roomId !== '') {
                    Rooms.findOne({id: roomId}).exec(function (err, room){
                        roomName = room.name; 
                        inviteLink = room.inviteLink;
                        roomsObj.name = roomName;
                        roomsObj.id = roomId;
                        roomsObj.inviteLink = inviteLink;

                        var channels = room.channels;
                        var i=0;
                        async.each(channels, function (channelId, callback2) {
                             chansObj = {};
                            Channels.findOne({id: channelId}).exec(function (err, channel){
                            chansObj.name = channel.channelName;
                            chansObj.id = channelId;
                            chansObj.type = channel.channelType;
                            chansArr.push(chansObj);
                            i++;
                            if(i===(channels.length-1)){
                              i=0;
                               callback1(); 
                            }else{
                            callback2();
                            }
                       });
                        }, 
                        function (err) {
                        });
                    }); 
                }

               }, function (err) {
                   roomsObj.channels = chansArr;
                    roomsArr.push(roomsObj);
                   sails.log(roomsArr);
               }); 
            });
        }
abdulbarik
  • 6,101
  • 5
  • 38
  • 59
0

I solved it, it really was a case for promises, I used bluebird promise combined with async - the modified code:

getRooms: function (req, res) {
            User.find({id: req.cookies.claver_id}).exec(function (err, result) {
               if (err) {
                  return res.send(400);
               }
               rooms = result[0].rooms;
               if (rooms.length === 1) {//No room defaults to ['']
                   return res.send(400);
               }

                var roomsObj = {};
                var roomsArr = [];//we will place the roomsObj inside the roomsArr

                var chansObj = {};
                var chansArr = [];
               Promise.each(rooms, function (roomId, callback1){
                    roomsObj = {};
                   if (roomId !== '') {
                    async.series ([
                      function () {
                          Rooms.findOne({id: roomId}).then(function (room){
                        roomName = room.name; 
                        inviteLink = room.inviteLink;
                        roomsObj.name = roomName;
                        roomsObj.id = roomId;
                        roomsObj.inviteLink = inviteLink;
                         channels = room.channels;
                         sails.log(roomName);
                         })
                     }
                     ]);
                      return   Promise.each(channels, function (channelId) {
                           return Promise.all([
                             Channels.findOne({id: channelId}).then(function (channel){
                            chansObj = {};
                            chansObj.name = channel.channelName;
                            chansObj.id = channelId;
                            chansObj.type = channel.channelType;
                            chansArr.push(chansObj);
                            sails.log(chansObj);
                          })
                           ]).then(function () {
                               sails.log('done one');

                           });
                        }).then(function () {
                             roomsObj.channels = chansArr; 
                             roomsArr.push(roomsObj);
                            sails.log('done all');
                            chansArr = [];

                        });
              }
               }).then(function () {
                        sails.log(roomsArr);
                        sails.log("grand finish");
                    });

            });
        }

Thanks to everyone who contributed.

Acheme Paul
  • 1,194
  • 15
  • 19