简体   繁体   中英

NodeJS getting data from multiple http requests

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)
    })
})

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)
        });
})

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)
        });
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM