Alex Wiley
Alex Wiley

Reputation: 325

Async request inside two Array.maps

I am creating an API to interface with my Google Cloud Firestore database. I am querying for 'pipelines' in my application. The request will return an array of pipelines (ie. an array of JSON objects). Each JSON object has a users attribute which is equal to an array of strings. Each string represents a user ID in my database.

What I am trying to do is map over each pipeline and then inside each pipeline map over the users array to make an asynchronous call to my database to fetch the information for that user by it's users ID.

I am running into difficulty waiting for all of the asynchronous requests to complete and to return the data correctly. Currently I have the following code:

pipelineResults.map(pipeline => {


    pipeline.users = pipeline.users.map(user => {
        return promises.push(db.collection('users')
            .doc(user)
            .get()
            .then(snapshot => {
                user = snapshot.data();
                console.log(user);
                return user;
            }));
    });

    return pipeline;

});

Promise.all(promises)
    .then(result => {
        res.send(pipelineResults);
    });

The pipelineResults JSON is defined as the following (before mapping over):

[
{
    "integrations": [
        {
            "dateAdded": {
                "_seconds": 1553435585,
                "_nanoseconds": 769000000
            },
            "vendorId": "abcdefg",
            "integrationId": "ahdhfyer",
            "addedBy": "xEcscnBo0PGgOEwb2LGj",
            "used": 1
        }
    ],
    "users": [
        "xEcscnBo0PGgOEwb2LGj"
    ],
    "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras nec augue dapibus, interdum felis ac, tristique nunc. Donec justo ex, pulvinar a nisl et, consequat porta nunc.",
    "scheduled": {
        "isScheduled": false
    },
    "orgId": "ae35gt654",
    "runInfo": null,
    "name": "Development pipeline",
    "teams": [
        {
            "users": [
                "xEcscnBo0PGgOEwb2LGj"
            ],
            "createdOn": {
                "_seconds": 1553435585,
                "_nanoseconds": 769000000
            },
            "id": "abfe4h6uuy",
            "createdBy": "xEcscnBo0PGgOEwb2LGj",
            "userCount": 1
        }
    ],
    "createdOn": {
        "_seconds": 1553435585,
        "_nanoseconds": 769000000
    },
    "createdBy": "xEcscnBo0PGgOEwb2LGj"
}
]

After running the above code to map over the pipelines and users, the user attribute on the pipeline is now just an array with 1 inside:

"users": [
        1
]

A user object should look like the following:

{ firstName: 'Alex',
  activeIntegrations: 14,
  position: 'Manager',
  email: '[email protected]',
  lastName: 'Wiley',
}

I'm pretty sure i'm not returning or waiting on an async call.

Summary Performing an async call inside two map functions.

Any help greatly appreciated.

Upvotes: 2

Views: 795

Answers (1)

Eugene Shilin
Eugene Shilin

Reputation: 461

You are trying to assign pipeline.users while promise is not resolved; try this:

Try this:

return Promise.all(pipelineResults.map(pipeline => {
    return Promise.all(pipeline.users.map(user => 
        db.collection('users')
            .doc(user)
            .get()
            .then(snapshot => {
                user = snapshot.data();
                console.log(user);
                return user;
            });
    ))
    .then(users => {
       pipeline.users = users;
    });    
}))
.then(() => res.send(pipelineResults));

Upvotes: 2

Related Questions