0

I have a big issue with my function in sails.js (v12). I'm trying to get all userDetail using async (v2.3) for deep populating my user info:

UserController.js:

 userDetail: function (req, res) {
    var currentUserID = authToken.getUserIDFromToken(req);
    async.auto({
        //Find the User
        user: function (cb) {
            User
                .findOne({ id: req.params.id })
                .populate('userFollowing')
                .populate('userFollower')
                .populate('trips', { sort: 'createdAt DESC' })
                .exec(function (err, foundedUser) {
                    if (err) {
                        return res.negotiate(err);
                    }
                    if (!foundedUser) {
                        return res.badRequest();
                    }
                    // console.log('foundedUser :', foundedUser);
                    cb(null, foundedUser);
                });
        },
        //Find me
        me: function (cb) {
            User
                .findOne({ id: currentUserID })
                .populate('myLikedTrips')
                .populate('userFollowing')
                .exec(function (err, user) {
                    var likedTripIDs = _.pluck(user.myLikedTrips, 'id');
                    var followingUserIDs = _.pluck(user.userFollowing, 'id');
                    cb(null, { likedTripIDs, followingUserIDs });
                });
        },

        populatedTrip: ['user', function (results, cb) {
            Trip.find({ id: _.pluck(results.user.trips, 'id') })
                .populate('comments')
                .populate('likes')
                .exec(function (err, tripsResults) {
                    if (err) {
                        return res.negotiate(err);
                    }
                    if (!tripsResults) {
                        return res.badRequest();
                    }
                    cb(null, _.indexBy(tripsResults, 'id'));
                });
        }],

        isLiked: ['populatedTrip', 'me', 'user', function (results, cb) {
            var me = results.me;
            async.map(results.user.trips, function (trip, callback) {
                trip = results.populatedTrip[trip.id];

                if (_.contains(me.likedTripIDs, trip.id)) {
                    trip.hasLiked = true;
                } else {
                    trip.hasLiked = false;
                }

                callback(null, trip);
            }, function (err, isLikedTrip) {
                if (err) {
                    return res.negotiate(err);
                }
                cb(null, isLikedTrip);
            });
        }]
    },

        function finish(err, data) {
            if (err) {
                console.log('err = ', err);
                return res.serverError(err);
            }

            var userFinal = data.user;
            //userFinal.trips = data.isLiked;
            userFinal.trips = "test";
            return res.json(userFinal);
        }
    );
},

I tried almost everthing to get this fix but nothing is working... I am able to get my array of trips(data.isLiked) but I couldn't get my userFInal trips.

I try to set string value on the userFinal.trips:

JSON response

 {
  "trips": [], // <-- my pb is here !! 
  "userFollower": [
    {
      "user": "5777fce1eeef472a1d69bafb",
      "follower": "57e44a8997974abc646b29ca",
      "id": "57efa5cf605b94666aca0f11"
    }
  ],
  "userFollowing": [
    {
      "user": "57e44a8997974abc646b29ca",
      "follower": "5777fce1eeef472a1d69bafb",
      "id": "5882099b9c0c9543706d74f6"
    }
  ],
  "email": "test2@test.com",
  "userName": "dany",
  "isPrivate": false,
  "bio": "Hello",
  "id": "5777fce1eeef472a1d69bafb"
}

Question

How should I do to get my array of trips (isLiked) paste to my user trips array? Why my results is not what I'm expecting to have?

Thank you for your answers.

Dan
  • 3
  • 3

1 Answers1

2

Use .toJSON() before overwriting any association in model.
Otherwise default toJSON implementation overrides any changes made to model associated data.

var userFinal = data.user.toJSON(); // Use of toJSON
userFinal.trips = data.isLiked;
return res.json(userFinal);

On another note, use JS .map or _.map in place of async.map as there is not asynchronous operation in inside function. Otherwise you may face RangeError: Maximum call stack size exceeded issue.

Also, it might be better to return any response from final callback only. (Remove res.negotiate, res.badRequest from async.auto's first argument). It allows to make response method terminal

Sangharsh
  • 2,999
  • 2
  • 15
  • 27