Leveraging async.js to perform in-depth population in sails.js

Facing a major challenge with my function in sails.js (v12). I am attempting to retrieve 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);
        }
    );
},

Tried several approaches to resolve this issue but nothing seems to be effective... I am successfully obtaining my array of trips (data.isLiked) but unable to populate my userFinal trips.

Attempted to assign a string value to userFinal.trips:

JSON response

 {
  "trips": [], // <-- issue lies here!! 
  "userFollower": [
    {
      "user": "5777fce1eeef472a1d69bafb",
      "follower": "57e44a8997974abc646b29ca",
      "id": "57efa5cf605b94666aca0f11"
    }
  ],
  "userFollowing": [
    {
      "user": "57e44a8997974abc646b29ca",
      "follower": "5777fce1eeef472a1d69bafb",
      "id": "5882099b9c0c9543706d74f6"
    }
  ],
  "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2c58495f581e6c58495f58024f4341">[email protected]</a>",
  "userName": "dany",
  "isPrivate": false,
  "bio": "Hello",
  "id": "5777fce1eeef472a1d69bafb"
}

Question

How can I merge my array of trips (isLiked) into my user trips array? Why are my results not as expected?

Appreciate your insights and suggestions.

Answer №1

Ensure to call .toJSON() prior to updating any association within the model.
Otherwise, the default toJSON behavior will overwrite any modifications made to the associated data in the model.

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

Additionally, consider utilizing JS .map or _.map instead of async.map when there are no asynchronous operations within the function. This will help avoid encountering a

RangeError: Maximum call stack size exceeded
issue.

It is also recommended to only return responses from the final callback. (Omit res.negotiate and res.badRequest from the first argument of async.auto). This practice enables the response method to be terminal

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking for assistance on how to use Express JS to make a post request to insert data with an array of objects into a database. Can anyone provide guidance?

While utilizing ExpressJS for serverside functionality, I encountered an issue when making a post call with multiple objects in an array. The error message displayed is as follows: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to t ...

Is the validity of the expression !args.value || args.value.length true?

After analyzing this segment of code, I noticed an interesting expression: !args.value || args.value.length For instance, consider the following scenario: let v = {}; console.log(!v.value); //outputs true console.log(v.value); //outputs undefined con ...

An array containing a list of URLs linked together

Here is the string I am working with: http://localhost/layerthemes/wp-content/uploads/2014/05/46430454_Subscription_XXL-4_mini.jpghttp://localhost/layerthemes/wp-content/uploads/2014/05/Eddy-Need-Remix-mp3-image.jpghttp://localhost/layerthemes/wp-content/ ...

Unraveling the mystery: Retrieving event.target.value in a React component

Having trouble accessing the event.target.value from a React child Component, but not an HTML tag? In this scenario: the Button tag (React Component) cannot access event.target.value, while the button tag (HTML tag) can. import React from "react"; impor ...

What is the best way to dynamically add and index dimensions of arrays in PHP?

In my PHP class, I have a complex array and two member functions The first one takes in two integers: one representing the dimension and the other the value: private $complexArray; function setValueToGivenDimension($dimension, $value) My goal is to set ...

Using Special Characters in React JS Applications

When handling CSV uploads with accented characters such as émily or ástha, I encountered the need to encode and pass them to the backend. Experimenting with different approaches, I tried adjusting the file type in FormData from 'text/plain' to ...

Looking for a way to transfer the value of a variable to a PHP variable using any script or code in PHP prior to submitting a form?

Within this form, the script dynamically updates the module dropdown list based on the selected project from the dropdown box. The value of the module list is captured in a text field with id='mm', and an alert box displays the value after each s ...

Trigger the mousemove event only after the mouse click event has been activated

I need help with my code. I want an onmousemove event to occur when I click and move the mouse. Can someone assist me please? </head> <body> <img id="myImgId" alt="" src="Chrysa ...

The Battle of Extends and Intersection in Typescript

Typescript's concept of extension is akin to C++'s inheritance. Intersection in Typescript involves creating a new object with all the properties from the intersected classes. Why utilize intersection when extends keyword can already merge ...

Is it possible to adjust the timezone settings on my GraphQL timestamp data?

I've come across a lot of helpful information regarding the usage of Date() and timezones, but something seems to be off. In my GraphQL setup (sourcing from Sanity), I have configured it to use formatString in this manner: export default function Minu ...

Utilize Bootstrap4 to position content above the navigation icon

I need assistance to modify my code so that it will have the following appearance: I successfully created a navigation bar icon and inserted the logo, but I am struggling to position the data above the navigation icon: My current code: <nav class="n ...

What method can I use to identify the most widely-used edition of a specific npm module?

While the npm registry does provide metrics on the most depended packages, have you ever wondered if it's possible to determine the most popular version of a specific package? For example, as a user considering upgrading to react-router^4.0.0, wouldn ...

What is the best way to add up the attributes of objects within an array and save the total to the main

I have a collection of objects, illustrated here: var obj = { "ABC" : { "name" : "ABC", "budget" : 0, "expense" : 0, "ledgers" : [{ "Actual1920": 10, "Budget1920": 20, }, { "Actual1920": 10, ...

JavaScript code for initiating the npm start command

Is it possible to include the npm-start command in a JavaScript script? Requirement: Develop a JS script capable of triggering the npm-start command. Operating System: Microsoft Windows I need to turn it into a Windows service. However, in the code snip ...

Need to know how to retrieve the li element in a ul that does not have an index of 2? I am aware of how to obtain the index greater than or less

I'm looking to hide all the li elements except for the one with a specific index. I've written some code to achieve this, but I'm wondering if there's a simpler way using jQuery. While jQuery provides methods like eq, gt, and lt, there ...

Control the HTML button's state according to the information received from the server

I am currently working with datatable Jquery and using an ajax call to retrieve data from the server. Let's assume that the database consists of three attributes: "Attribute1, Attribute2, Status". Depending on the Status attribute, I need to enable or ...

Is it possible to programmatically include a getter method to a class in JavaScript or TypeScript?

My current focus is on TypeScript and I'm exploring the decorators functionality. I would greatly appreciate some guidance or expert knowledge on JavaScript capabilities in this area. I am curious about dynamically adding a getter method to a Prototy ...

Adding Axios package to a Vue 3 project without using the CLI

I'm facing an issue while trying to integrate the Axios package into my Vue 3 project that is not CLI-based. I initially attempted to include the package within the script tags at the top of the page, but that approach failed. Next, I tried creating a ...

Tips for incorporating an additional dataset bar using chart.js

I'm having a bit of trouble trying to modify the following script. Currently, it only displays one bar per label, but I need it to show 2 bars per label. Despite my numerous attempts using different variations with and without commas and "{}", I can&a ...

A guide on switching the status of various inputs in a table based on the selection of a radio button

In the scenario below, let's consider the following HTML structure: <tr> <td> <label for="c1_testRdio">Have you taken any tests in this class?:</label> <br> <label>Yes<input type="rad ...