NodeJS getting data from multiple http requests

node js sequential http requests
node js parallel http requests
nodejs synchronous http request
npm request
nodejs http request
node.js request
node js multiple api calls
nodejs fetch

I have an API when triggered it sent 2 HTTP Get Requests

I want to get the response from the 1st Get Request and store it in a variable

so I can send it with the response of the 2nd Get Request. What is the best way to achieve it

Here is what I tried to do

    dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    getRequest(memberLastLoginURL)
        .then(response => {
            let lastLoginTime = response.data.result
        })
        .catch(errorMessage => {
            console.log( 'Member Last Login API ERROR: ' + errorMessage)
            res.json(errorMessage)
        });
    getRequest(memberProfileStatsURL)
        .then(response => {
            let stats = response.data.result
            let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
            let totalPoints = stats.totalPoints
            res.json({
                data: {
                    totalPoints: stats.totalPoints,
                    totalPointsRedeemed: stats.totalPointsRedeemed,
                    availablePoints: (stats.totalPoints - stats.totalPointsRedeemed),
                    totalSessionTime: secondsToHm(stats.totalSessionTime), //convert sessionTime seconds to hours
                    loginsCount: stats.totalSessions,
                    rank: rank(totalPoints, pointsRank),
                    createdTime: stats.created,
                    lastLoginTime: lastLoginTime,
                },
                result: response.data.httpStatusCode
            })
        })
        .catch(errorMessage => {
            res.json(errorMessage)
        });
})

But i get lastLoginTime is not defined

If you want the request to run in parallel, you can start them both and then wait for both of them with Promise.all. Then, when both are done, use the results from both of them to send the response:

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    // *** Start the requests in parallel
    Promise.all([
        getRequest(memberLastLoginURL)
            .then(response => {
                return response.data.result
            }),
        getRequest(memberProfileStatsURL)
            .then(response => {
                return response.data.result // *** If this is a common thing, consider a wrapper
            })                              //     function for `getRequest` so we don't have to
    ])                                      //     re-write this fulfillment handler repeatedly
    .then(([lastLoginTime, memberStats]) => {
        // *** Both are done, send response
        let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
        let totalPoints = memberStats.totalPoints
        res.json({
            data: {
                totalPoints: memberStats.totalPoints,
                totalPointsRedeemed: memberStats.totalPointsRedeemed,
                availablePoints: (memberStats.totalPoints - memberStats.totalPointsRedeemed),
                totalSessionTime: secondsToHm(memberStats.totalSessionTime), //convert sessionTime seconds to hours
                loginsCount: memberStats.totalSessions,
                rank: rank(totalPoints, pointsRank),
                createdTime: memberStats.created,
                lastLoginTime: lastLoginTime,
            },
            result: 200 // *** Presumably this is 200 (or 200 is close enough), since this is a successful response
        })
    })
    .catch(errorMessage => {
        console.log( 'You'll want to update this error message: ' + errorMessage)
        res.json(errorMessage)
    })
})

Note that Promise.all's promise gets fulfilled with an array of the results in the same order as the promises fed into it.


Note that in the above it's sending 200, specifically, instead of response.data.httpStatusCode for the result. But if you really need the response.data.httpStatusCode from the memberProfileStatsURL call, you can pass it along to the final fulfillment handler like this:

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    // *** Start the requests in parallel
    Promise.all([
        getRequest(memberLastLoginURL)
            .then(response => {
                return response.data.result
            }),
        getRequest(memberProfileStatsURL)
            .then(response => {
                return {memberStats: response.data.result, httpStatusCode: response.data.httpStatusCode};
            })
    ])
    .then(([lastLoginTime, {memberStats, httpStatusCode}]) => {
        // *** Both are done, send response
        let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
        let totalPoints = memberStats.totalPoints
        res.json({
            data: {
                totalPoints: memberStats.totalPoints,
                totalPointsRedeemed: memberStats.totalPointsRedeemed,
                availablePoints: (memberStats.totalPoints - memberStats.totalPointsRedeemed),
                totalSessionTime: secondsToHm(memberStats.totalSessionTime), //convert sessionTime seconds to hours
                loginsCount: memberStats.totalSessions,
                rank: rank(totalPoints, pointsRank),
                createdTime: memberStats.created,
                lastLoginTime: lastLoginTime,
            },
            result: httpStatusCode
        })
    })
    .catch(errorMessage => {
        console.log( 'You'll want to update this error message: ' + errorMessage)
        res.json(errorMessage)
    })
})

7 Ways to Make HTTP Requests in Node.js, to learn how to make different HTTP requests in Node.js using Axios, Needle, new developers to learn how to make HTTP requests to exchange data. https .get('https://jsonplaceholder.typicode.com/todos/1', (response)� Now let's look at some real world examples of concurrency. We'll be making a function that sends multiple HTTP requests, first by the function which takes a callback and then invoking that function sequentially, concurrently and finally in parallel with the help of the cluster module.

First of all you are creating your variable inside the promise so the other promise can't read the value. Second you need to wait to the response.

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, async (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    let lastLoginTime = await getRequest(memberLastLoginURL)
        .then(response => {
            return response.data.result
        })
        .catch(errorMessage => {
            console.log( 'Member Last Login API ERROR: ' + errorMessage)
            res.json(errorMessage)
        });
    getRequest(memberProfileStatsURL)
        .then(response => {
            let stats = response.data.result
            let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
            let totalPoints = stats.totalPoints
            res.json({
                data: {
                    totalPoints: stats.totalPoints,
                    totalPointsRedeemed: stats.totalPointsRedeemed,
                    availablePoints: (stats.totalPoints - stats.totalPointsRedeemed),
                    totalSessionTime: secondsToHm(stats.totalSessionTime), //convert sessionTime seconds to hours
                    loginsCount: stats.totalSessions,
                    rank: rank(totalPoints, pointsRank),
                    createdTime: stats.created,
                    lastLoginTime: lastLoginTime,
                },
                result: response.data.httpStatusCode
            })
        })
        .catch(errorMessage => {
            res.json(errorMessage)
        });
})

4 + 1 ways for making HTTP requests with Node.js: async/await edition, HTTP requests are a means for fetching data from a remote source. will need some code to get meaningful data from one of those remote sources. How to make HTTP requests in Node.js with various modules; pros and� GET and POST is two common HTTP Requests used for building REST APIs. Both of these calls are meant for some special purpose. As per the documentation GET requests are meant to fetch data from specified resource and POST requests are meant to submit data to a specified resource.

You are trying to access lastLoginTime - the scope of which is accessible only inside your first getRequest.

Since you want to use the result of your first request in your second getRequest you should do it once you get the successful response from your first getRequesy. The correct way to do this in your code is

dummy.get("/api/dummy/memberProfileStats", isAuthenticated, (req, res) => {
    const userId = res.locals.user
    const memberProfileStatsURL = `/api/reports/users/${userId}/general`
    const memberLastLoginURL = `/api/users/${userId}/lastlogin`
    getRequest(memberLastLoginURL)
        .then(response => {
            let lastLoginTime = response.data.result
            getRequest(memberProfileStatsURL)
            .then(response => {
                let stats = response.data.result
                let pointsRank = [150, 500, 1000, 2000, 3500, 5000, 5500]
                let totalPoints = stats.totalPoints
                res.json({
                    data: {
                        totalPoints: stats.totalPoints,
                        totalPointsRedeemed: stats.totalPointsRedeemed,
                        availablePoints: (stats.totalPoints - stats.totalPointsRedeemed),
                        totalSessionTime: secondsToHm(stats.totalSessionTime), //convert sessionTime seconds to hours
                        loginsCount: stats.totalSessions,
                        rank: rank(totalPoints, pointsRank),
                        createdTime: stats.created,
                        lastLoginTime: lastLoginTime,
                    },
                    result: response.data.httpStatusCode
                })
            })
            .catch(errorMessage => {
                res.json(errorMessage)
            });
        })
        .catch(errorMessage => {
            console.log( 'Member Last Login API ERROR: ' + errorMessage)
            res.json(errorMessage)
        });
})

5 Ways to Make HTTP Requests in Node.js using Async/Await, 5 Ways to Make HTTP Requests in Node.js using Async/Await for modern languages and one of the first things many developers learn when It may take a bit more effort to get the data you want, but is a great utility if you� Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Another extremely common programming task is making an HTTP request to a web server.

Anatomy of an HTTP Transaction, We'll assume that you know, in a general sense, how HTTP requests work, regardless of Getting at the body data is a little more involved than accessing request headers. Note: This may seem a tad tedious, and in many cases, it is. Luckily� Then, a global array variable (request in case of Node.js) is initialised with the data stored in this session file. Thus, this authentication data is preserved with all sequential incoming requests and the user is kept logged in throughout the session until he or she manually logs off.

HTTP, Servers may also refuse to allow multiple requests over the same connection, in which case By providing {agent: false} as an option to the http.get() or http. request() However, if a 'response' event handler is added, then the data from the� http request – used for making http requests i.e an http client. The http request node can be used for. Retrieving web pages from a website; Making API Request; Sending and receiving JSON data to a website or API. etc; The node will send a request and receive the response. The node handles both the request and response.

Combine multiple requests in one HTTP call using JSON batching , For example, a client might want to compose a view of unrelated data such as: An image stored in OneDrive; A list of Planner tasks; The calendar�

Comments
  • At least related: stackoverflow.com/questions/500431/…
  • codetower.github.io/es6-features/#Let - Read this reference, And you have to handle asynchronous properly
  • I get try is expected when i used your code it have syntax error
  • @mohamedadel - I was missing a closing ) on the parameter list of the fulfillment (then) handler on the Promise.all promise, I've fixed it. It also had an extra [ in it! Sloppy of me...
  • @mohamedadel - Ah, I missed you were using that. Basically, just pass it from the relevant fulfillment handler to that handler. But surely the status code is 200? After all, this is a successfully-completed response...
  • @mohamedadel - No worries! I added a version that would use the httpStatusCode from the memberProfileStatsURL call, just in case you needed it. Happy coding!
  • @mohamedadel - You follow the same pattern (if you want it in parallel with the others), add it as a third entry in the array passed to Promise.all, and then add a third entry to the array destructuring in the fulfillment handler on the promise. See the MDN link above for more on Promise.all. If you wanted the request to wait and be done after one of the others, you'd put it in the fulfillment handler for the request you want it to wait for. This answer may also help.
  • Why? What did you change? How does the change help?
  • @T.J.Crowder Your solution is what i tried to answer. But i did not use promise.all Instead what i thought is he can use the response of the first request atleast even though his second getRequest fails. But downvoting for that is really sad :(