response.send is not a function - node.js

I am writing a firebase function for the webhook fulfillment of dialogflow chatbot. It keeps generating error that response.send is not a function
const functions = require('firebase-functions');
var request1 = require('request')
exports.webhook = functions.https.onRequest((request, response) => {
console.log("request.body.result.parameters: ", request.body.result.parameters);
let params = request.body.result.parameters;
var options = {
url: `https://islam360api.herokuapp.com/${params.find}`,
json:true
}
request1(options, function(error, response, body){
if(error) response.send({speech: "error in API call"});
else response.send({speech: body.speech});
});
});
Firebase Logs

Problem: this is a problem of shadow variable name, when you are trying to send response using firebase functions response object, in fact you are sending response back on response object of npm request module which is ofcourse not possible
Solution:
just put an underscore or change the spelling and you are ready to go, have a look of code:
(notice change in 5th line from bottom)
const functions = require('firebase-functions');
var request1 = require('request')
exports.webhook = functions.https.onRequest((request, response) => {
console.log("request.body.result.parameters: ", request.body.result.parameters);
let params = request.body.result.parameters;
var options = {
url: `https://islam360api.herokuapp.com/${params.find}`,
json:true
}
request1(options, function(error, _response, body){
if(error) response.send({speech: "error in API call"});
else response.send({speech: body.speech});
});
});

Related

How do I read request header without Express

Simply, I have a function that gets the weather using request library. I want to see my request header but all the topics I looked at used with Express. How can I do this ?
const request = require('request');
function getDegree(cityURL){
request.get({
url:cityURL
}, (err, res, body)=>{
if (err) console.log(err);
//My standart codes
console.log(temps);
//I want console.log(requestHeader) or something like this here, for example.
})
}
You can read the request headers by storing it inside a variable (myRequest), then use myRequest.headers.
const request = require("request");
var myRequest = request.get(options, (err, res, body) => {
console.log(requestHeaders);
});
var requestHeaders = myRequest.headers;

Update the variable value after asynchronous http call

I have a firebase function called getRequest which contains simple http calls using request npm package and a variable named result which will should contain the body response from the http call after request completed.
However, the request output is a "this should be replaced" string, because the http call runs asynchronously.
How do you get the result variable to contain the body response from the http call?
const functions = require('firebase-functions');
const request = require('request');
exports.getRequest = functions.https.onRequest(() => {
let result = "this should be replaced";
request('http://worldclockapi.com/api/json/est/now', function(error,response,body){
if (!error && response.statusCode == 200)
result = body;
});
console.log(result);
});
I've tried to use callback but I'm confused to put the parameter, because actually this is also inside the callback.
request supports callback interfaces natively but does not return a promise. You must wait the asynchronous call to the external API is finished before sending back the response, and for this you should use a Promise which will resolves when the call to the API returns.
You can use the request-promise library and the rp() method which "returns a regular Promises/A+ compliant promise" and then, adapt your code as follows:
const functions = require('firebase-functions');
const rp = require('request-promise');
exports.getRequest = functions.https.onRequest((req, res) => {
let result = "this should be replaced";
var options = {
uri: 'http://worldclockapi.com/api/json/est/now',
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(parsedBody => {
result = parsedBody.currentDateTime;
console.log(result);
res.send( {result} );
})
.catch(err => {
// API call failed...
res.status(500).send({'Error': err});
});
});
I would suggest you watch the official Video Series (https://firebase.google.com/docs/functions/video-series/) which explains the key point about returning Promises and also how to handle errors in an HTTP Cloud Function.
Two extra points to note:
onRequest() arguments
You need to pass two arguments to the onRequest() function: the Request and theResponse` objects, see https://firebase.google.com/docs/functions/http-events?authuser=0#trigger_a_function_with_an_http_request
exports.date = functions.https.onRequest((req, res) => {
// ...
});
Pricing plan
You need to be on the "Flame" or "Blaze" pricing plan.
As a matter of fact, the free "Spark" plan "allows outbound network requests only to Google-owned services". See https://firebase.google.com/pricing/ (hover your mouse on the question mark situated after the "Cloud Functions" title)
Since the worldclock API is not a Google-owned service, you need to switch to the "Flame" or "Blaze" plan.
the callback calls asynchronous, so console.log(result) call before the callback run.
if you want to print the result variable with content from the requet you need to print it from the callback
const functions = require('firebase-functions');
const request = require('request');
exports.getRequest = functions.https.onRequest(() => {
let result = "this should be replaced";
request('http://worldclockapi.com/api/json/est/now', function(error,response,body){
if (!error && response.statusCode == 200)
result = body;
console.log(result);
});
});
however, I recommend request-promise and use async/await syntax
const functions = require('firebase-functions');
const request = require('request-promise');
exports.getRequest = functions.https.onRequest(async () => {
let result = "this should be replaced";
result = await request('http://worldclockapi.com/api/json/est/now');
console.log(result);
});

NodeJS http get method access url in response function

I want to access http request url and parameters in callback function. When I print id with console.log I get error is id undefined. How can I access id and request url?
const Request = require('request');
var id=5;
Request.get('https://example.com/'+id, function (error, response, body) {
console.log("id", id);
}
});
Your code works .may be some syntax error issue,this is the updated
code. I tested it in my console and is working fine.
const Request = require('request');
var id=5;
Request.get('https://example.com/'+id, function (error, response, body) {
if(error) {
return console.dir(error);
}
console.log("id", id);
});
You might need to have a look at the official documentation of the Request package-here and link which explains its usage in detail

Cannot promisify an API that has normal methods with 'Async'-suffix

I am trying to call soap web service using node. I have used soap and request packages.
Below is the code snippet :
var express = require('express');
var Promise = require("bluebird");
var app = express();
var soap = require('soap')
var url = 'http://example.com?WSDL';
let request = require('request');
let request_with_defaults = request.defaults({
'proxy': 'http://example.com:80',
'timeout': 5000,
'connection': 'keep-alive'
});
let soap_client_options = {
'request': request_with_defaults
};
var args = {
requestId: '1406303'
};
soap.createClient(url, soap_client_options, function(err, client) {
var soapHeader = {
"Username": "test",
"Password" : "test"
};
client.addSoapHeader(soapHeader);
client.getESSJobStatus(args, function(err, result) {
if(err){
console.log('Error occured');
}
console.log(result);
});
})
here i am getting error :
throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a See http://bluebirdjs.com/docs/error-explanations.htmlX\u000a"
TypeError: Cannot promisify an API that has normal methods with 'Async'-suffix
See http://bluebirdjs.com/docs/error-explanations.html
I have checked this url. it is saying that async task gets created which is not able to call. But i am not able to relate this.
can anyone help me with code how can i resolve this issue?
Try Promise.promisifyAll(require('soap'), {suffix: 'MySuffix'});

How to Store the Response of a GET Request In a Local Variable In Node JS

I know the way to make a GET request to a URL using the request module. Eventually, the code just prints the GET response within the command shell from where it has been spawned.
How do I store these GET response in a local variable so that I can use it else where in the program?
This is the code i use:
var request = require("request");
request("http://www.stackoverflow.com", function(error, response, body) {
console.log(body);
});
The easiest way (but it has pitfalls--see below) is to move body into the scope of the module.
var request = require("request");
var body;
request("http://www.stackoverflow.com", function(error, response, data) {
body = data;
});
However, this may encourage errors. For example, you might be inclined to put console.log(body) right after the call to request().
var request = require("request");
var body;
request("http://www.stackoverflow.com", function(error, response, data) {
body = data;
});
console.log(body); // THIS WILL NOT WORK!
This will not work because request() is asynchronous, so it returns control before body is set in the callback.
You might be better served by creating body as an event emitter and subscribing to events.
var request = require("request");
var EventEmitter = require("events").EventEmitter;
var body = new EventEmitter();
request("http://www.stackoverflow.com", function(error, response, data) {
body.data = data;
body.emit('update');
});
body.on('update', function () {
console.log(body.data); // HOORAY! THIS WORKS!
});
Another option is to switch to using promises.

Resources