I am trying to make a http request with node module http
on an azure function with javascript and for some reason http.request
is not receiving data(no error printed its like the requested is blocked). There is anything wrong with azure configuration or the code?Am i missing something really obvious?
Code is running fine on local js file
context.log('JavaScript timer trigger function ran!', timeStamp);
printed as expected but context.log("SUCCESS", JSON.parse(data));
not printed at all.
Also tryed different libraries (request, axios) with no success
module.exports = async function (context, myTimer) {
var timeStamp = new Date().toISOString();
if (myTimer.IsPastDue)
{
context.log('JavaScript is running late!');
}
context.log('JavaScript timer trigger function ran!', timeStamp);
const http = require('http');
http.get('http://myAPIurl', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
context.log("SUCCESS", JSON.parse(data));
});
}).on("error", (err) => {
context.log("ERROR: " + err.message);
});
}
I am trying to make a http request with node module http
on an azure function with javascript and for some reason http.request
is not receiving data(no error printed its like the requested is blocked). There is anything wrong with azure configuration or the code?Am i missing something really obvious?
Code is running fine on local js file
context.log('JavaScript timer trigger function ran!', timeStamp);
printed as expected but context.log("SUCCESS", JSON.parse(data));
not printed at all.
Also tryed different libraries (request, axios) with no success
module.exports = async function (context, myTimer) {
var timeStamp = new Date().toISOString();
if (myTimer.IsPastDue)
{
context.log('JavaScript is running late!');
}
context.log('JavaScript timer trigger function ran!', timeStamp);
const http = require('http');
http.get('http://myAPIurl', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
context.log("SUCCESS", JSON.parse(data));
});
}).on("error", (err) => {
context.log("ERROR: " + err.message);
});
}
Share
Improve this question
asked Jun 4, 2019 at 21:33
Panos KPanos K
1,0911 gold badge13 silver badges27 bronze badges
8
- You shouldn't be mixing async and callbacks, your function execution is likely returning before your callback gets called. If you change your code to be awaitable I think you should start seeing the results you expect. – nelak Commented Jun 5, 2019 at 0:50
- @nelak I removed async and still not working also tryed to put await on http without success, maybe you have a minimal working example that i can work with? – Panos K Commented Jun 5, 2019 at 7:14
-
Can you check that the
http
module is part of your dependencies? stackoverflow./questions/36461247/… – Thomas Commented Jun 5, 2019 at 9:46 - yes http module loaded properly – Panos K Commented Jun 5, 2019 at 15:35
- Are you using function runtime version 1 or 2 (learn.microsoft./en-us/azure/azure-functions/…)? – technogeek1995 Commented Jun 5, 2019 at 15:38
2 Answers
Reset to default 8I rewrote your code using Axios. It has support for async/await out of the box, and simplifies a lot of the code to function as your would expect since it makes asynchronous code perform like synchronous code.
I think the main issue you may have been running into it that everything in JavaScript is async. As a result, the Azure Function runtime was exiting before your async function finished since it didn't block like synchronous code would when making the HTTP request. If you want to use callbacks, you need to call context.done()
inside your callback function so the Azure Function doesn't exit before the callback is pleted. By using async/await, you can guarantee that your code will block on the HTTP request until it receives a response or timeout. In the example below, Axios will return a response object that includes data as an element. I'm extracting data with a deconstruction operation, which allows me to log data
.
const axios = require('axios');
const url = 'https://google.';
module.exports = async function (context, myTimer) {
try {
const { data } = await axios.get(url);
context.log(data);
// do something with the data
return data;
} catch (err) {
context.log(err);
// do something with the error
}
context.done();
}
To Install a Package on an Azure Function
- Go to the Azure Portal; select your Azure Function App
- Select
Platform Features
. ThenAdvanced Tools (Kudu)
under Development Tools - Using the file explorer, navigate to
site/wwwroot/
. You should see apackage.json
file in there, and several folders each with the name of your functions. - From that directory, run
npm install --save axios
- To confirm it worked, edit your
package.json
with the pencil icon.axios
should be listed underdependencies
json element
I've kept your code callback based.
I removed the async
moniker from the definition and added a call to context.done
(this signals the functions host when your function has ended) in your resp.end
handler
module.exports = function (context, myTimer) {
var timeStamp = new Date().toISOString();
if (myTimer.IsPastDue)
{
context.log('JavaScript is running late!');
}
context.log('JavaScript timer trigger function ran!', timeStamp);
const https = require('https');
https.get('https://raw.githubusercontent./LearnWebCode/json example/master/animals-1.json', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
context.log("SUCCESS", JSON.parse(data));
context.done(null, data);
});
}).on("error", (err) => {
context.log("ERROR: " + err.message);
});
}
Another option would be to keep the function as async
but you'd need to replace the callbacks with promise
based calls. In some scenarios this can be achieved by wrapping them using util.promisify and then calling them with the await
keyword