Reputation: 715
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
Upvotes: 2
Views: 73
Reputation: 1074295
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)
})
})
Upvotes: 4
Reputation: 1967
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)
});
})
Upvotes: 1
Reputation: 66
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)
});
})
Upvotes: 1