Reputation: 542
I'm new to both GCF and Javascript async and have been struggling with this. I perform a fetch call initially and then pass that response as a parameter to a second function which then also performs a separate fetch call.
During the second function, my empty initialized json gets properties added to it, and when that function completes, I want to notify the exports.helloHttp
to then do res.end
and terminate.
I've tried chaining an additional empty then()
but it doesn't seem to be working.
My code:
var json = {}; // <- gets properties added to it during secondFunction()
exports.helloHttp = (req, res) => {
fetch("firstfetchurl.com",requestOptions)
.then(result => result.json())
.then(response => {
// next take the result and create a new product
return secondFunction(response);
})
.catch(error => console.log('error', error));
// res.end(JSON.stringify(json)); <- this is what I want my cloud function to output, but only after secondFunction completes
};
Upvotes: 1
Views: 1369
Reputation: 6133
Here is the code that would do what you want (replace the fetch URLs and set the appropriate options)
const fetch = require('node-fetch');
exports.helloHttp = async (req, res) => {
return fetch("https://jsonplaceholder.typicode.com/users/1/albums") // First fetch
.then(firstFetchResponse => firstFetchResponse.json())
.then(firstFetchResponse => secondFunction(firstFetchResponse)) // Second fetch
.then(secondFunctionResponse => secondFunctionResponse.json())
.then(finalResponse => res.json(finalResponse)) // This line sends your response to the client
.catch(error => { console.error('Error', error); res.status(500).send('Server Error') }); // In case an error, log and send an error response
};
async function secondFunction(data) {
// Logic of your second function. Here just does another fetch using the data from the first request
let firstAlbumId = data[0].id
return fetch(`https://jsonplaceholder.typicode.com/albums/${firstAlbumId}/photos`);
}
The same function can use an await
like this
exports.helloHttp = async (req, res) => {
try {
let response = await fetch("https://jsonplaceholder.typicode.com/users/1/albums") // Note the await on this line
.then(result => result.json())
.then(firstFetchResponse => secondFunction(firstFetchResponse))
.then(secondFetchResponse => secondFetchResponse.json());
res.json(response); // Finally you are sending the response here.
} catch (error) {
console.error(error);
res.status(500).send('Server Error');
}
};
Finally you would also need to make sure that the package.json
has the dependency for node-fetch
{
"name": "sample-http",
"version": "0.0.1",
"dependencies": {
"node-fetch": "^2.6.0" // This line must be there
}
}
For sending the JSON response, it uses this method.
Upvotes: 3
Reputation: 83048
result.json()
is not an asynchronous operation, therefore you don't need to use a then()
block. The following should do the trick;
exports.helloHttp = (req, res) => {
fetch("firstfetchurl.com",requestOptions)
.then(result => {
return secondFunction(result.json());
})
.catch(error => console.log('error', error));
//...
Note that, depending on the exact goal of you helloHttp
function, you may need to return the entire promises chain, as follows:
exports.helloHttp = (req, res) => {
return fetch("firstfetchurl.com",requestOptions) // Note the return
.then(result => {
return secondFunction(result.json());
})
.catch(error => console.log('error', error));
//...
Upvotes: 0