Use a value from a function into another function nodejs express - javascript

I want to return the value that has been declared in the first Function CreateTag and using it as variable in the second Function CreateStream, but it won't work..
I'm working with nodejs Express.
I try to use RETURN but it won't work..
I have tried it in differance ways, but still not work..
Can you someone help me, please?
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
//Function 1: createTag
var createTag = function hi (TanentValue) {
var https = require('https');
var data = JSON.stringify({
name: TanentValue,
schemaPath: "Tag"
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/tag?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
var req = https.request(options, (res) => {
//console.log(res)
res.on('data', (d) => {
console.log("hi tag")
var getResult = "GaLvAnI"; // ----> return this and use it into the function createStream
return getResult;
})
})
;
req.on('error', (error) => {
console.error(error)
});
req.write(data);
req.end();
}
//Function 2: createStream
var createStream = function (TanentValue) {
var https = require('https');
var galvani = hi(); // --------> here I made a variable to call return value
var data = JSON.stringify({
name: TanentValue,
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/stream?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
var req = https.request(options, (res) => {
res.on('data', (d) => {
console.log(galvani); // -----> use the variable here
})
})
;
req.on('error', (error) => {
console.error(error)
});
req.write(data);
req.end();
}
//homepage
router.get('/', function (req, res) {
res.render('index', { title: 'MCS Test' });
});
//create
router.post('/create', function (req, res) {
//create tag
console.log('POST / Call Create Tag');
createTag(req.body.TanentValue);
//create stream
console.log('POST / Call Create Stream');
createStream(req.body.TanentValue);
res.send('Stream and Tag has been created');
});
module.exports = router;

you can not directly return value from async function. you have to use promise. something like this:
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
//Function 1: createTag
var createTag = function (TanentValue) { // function should be anonymouse
return new Promise((resolve, reject) => {
var https = require('https');
var data = JSON.stringify({
name: TanentValue,
schemaPath: "Tag"
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/tag?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
var req = https.request(options, (res) => {
//console.log(res)
res.on('data', (d) => {
console.log("hi tag")
var getResult = "GaLvAnI"; // ----> return this and use it into the function createStream
resolve(getResult); // success call
})
})
;
req.on('error', (error) => {
reject(error); // error call
});
req.write(data);
req.end();
});
}
//Function 2: createStream
var createStream = function (TanentValue) {
createTag().then((val) => {
var https = require('https');
var galvani = val; // use that value from sucess call
var data = JSON.stringify({
name: TanentValue,
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/stream?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
var req = https.request(options, (res) => {
res.on('data', (d) => {
console.log(galvani); // -----> use the variable here
})
})
;
req.on('error', (error) => {
console.error(error)
});
req.write(data);
req.end();
})
.catch((error) => {
// handle error from createTag function here
});
}
//homepage
router.get('/', function (req, res) {
res.render('index', { title: 'MCS Test' });
});
//create
router.post('/create', function (req, res) {
//create tag
console.log('POST / Call Create Tag');
createTag(req.body.TanentValue);
//create stream
console.log('POST / Call Create Stream');
createStream(req.body.TanentValue);
res.send('Stream and Tag has been created');
});
module.exports = router;

You can solve it using just callback function or the promise.
Using callbacks.
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
//Function 1: createTag
var createTag = (TanentValue, callback) => {
var https = require('https');
var data = JSON.stringify({
name: TanentValue,
schemaPath: "Tag"
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/tag?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
var req = https.request(options, (res) => {
res.on('data', (d) => {
console.log("hi tag")
var getResult = "GaLvAnI"; // ----> return this and use it into the function createStream
callback(false, getResult);
})
});
req.on('error', (error) => {
//console.error(error)
callback(true, error);
});
req.write(data);
req.end();
}
//Function 2: createStream
var createStream = (TanentValue, callback) => {
var https = require('https');
var data = JSON.stringify({
name: TanentValue,
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/stream?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
createTag(TanentValue, (is_error, galvani) => {
if(err || !data){
// do error handling...
callback(true); // true for there was an error
}else{
var req = https.request(options, (res) => {
res.on('data', (d) => {
callback(false);
console.log(galvani); // -----> use the variable here
})
});
req.on('error', (error) => {
callback(true);
console.error(error)
});
req.write(data);
req.end();
}
})
}
//homepage
router.get('/', function (req, res) {
res.render('index', { title: 'MCS Test' });
});
//create
router.post('/create', function (req, res) {
/*
// Since the stream seems to depend on the tag created,
// you don't need to call createTag explicitly because
// it is always/already called from createStream.
//create tag
console.log('POST / Call Create Tag');
createTag(req.body.TanentValue, function(is_error, data){
if(!is_error){
// do something
}else{
// do error handling
console.error(error);
res.send('Tag could not be created, please try later again..');
}
});
*/
//create stream
console.log('POST / Call Create Stream');
createStream(req.body.TanentValue, is_error => {
if(!is_error){
res.send('Stream and Tag has been created');
}else{
res.send('Stream could not be created, please try later again..');
}
});
});
module.exports = router;
Using Promise
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
//Function 1: createTag
var createTag = TanentValue => {
var https = require('https');
var data = JSON.stringify({
name: TanentValue,
schemaPath: "Tag"
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/tag?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
return new Promise((resolve, reject) => {
var req = https.request(options, (res) => {
res.on('data', (d) => {
console.log("hi tag")
var getResult = "GaLvAnI"; // ----> return this and use it into the function createStream
resolve(getResult);
})
});
req.on('error', (error) => {
//console.error(error)
reject(error);
});
req.write(data);
req.end();
})
}
//Function 2: createStream
var createStream = TanentValue => {
var https = require('https');
var data = JSON.stringify({
name: TanentValue,
});
var options = {
hostname: 'qlik_dev.be',
path: '/meteor/qrs/stream?xrfkey=1234567890123456',
method: 'POST',
headers: {
'x-qlik-xrfkey': '1234567890123456',
'hdr-usr': 'gak\\gaka',
'Content-Type': 'application/json'
},
};
createTag(TanentValue).then( galvani => {
return new Promise((resolve, reject) => {
var req = https.request(options, (res) => {
res.on('data', (d) => {
console.log(galvani); // -----> use the variable here
resolve(d);
})
});
req.on('error', (error) => {
console.error(error)
reject({ msg: 'request error while creating the stream', error: error})
});
req.write(data);
req.end();
})
}).catch( error => {
// do error handling...
reject({msg: 'Error while creating a tag', error: error}); // true for there was an error
});
}
//homepage
router.get('/', function (req, res) {
res.render('index', { title: 'MCS Test' });
});
//create
router.post('/create', function (req, res) {
/*
// Since the stream seems to depend on the tag created,
// you don't need to call createTag explicitly because
// it is always/already called from createStream.
//create tag
console.log('POST / Call Create Tag');
createTag(req.body.TanentValue).then( data => {
// do something
}).catch( error => {
// do error handling
});
*/
//create stream
console.log('POST / Call Create Stream');
createStream(req.body.TanentValue).then( data => {
res.send('Stream and Tag has been created');
}).catch(error => {
// 'Stream could not be created, please try later again..'
res.send(error.msg);
});
});
module.exports = router;

Very handfull!! thank you it works!
But while passing the data (Json) from function 1 to function 2 with Promise, the data (json) is undefine in function 2. If I pass a data (String) from function 1 to function 2 than it works..
Why does it give me 'undefine' when it is a json?
//var id;
var req = https.request(options, (res) => {
//console.log(res)
res.setEncoding('utf8');
res.on('data', function (data) {
var json = JSON.parse(data);
var TagId = JSON.stringify(json[0]);
console.log("2 hi getTap");
console.log(TagId); // -------> here it works well
resolve(TagId);
});
});
var req = https.request(options, (res) => {
res.on('data', (d) => {
console.log("3 hi createStream");
console.log(galvani); // -------> here it doesn't work.. it gives me undefine
})
});
here a printscreen of response

Related

Return a response's body when using the await/async operators

I'm trying to convert a function that returns a Promise, to one that that uses await/async (which returns an implicit Promise, I understand).
This function "wraps" a call to the https.request object, the key part being the resolve(body) that returns the response's body:
promise_it = (data) => {
// throws FATAL
if (!data) {throw new Error('data is missing');}
return new Promise((resolve, reject) => {
let postData = JSON.stringify(data);
let options = {
hostname: 'httpbin.org',
port: 443,
path: '/post',
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// Accept: 'application/json'
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
const https = require('https');
let req = https.request(options, (res) => {
let body = [];
res.on('data', function(chunk) {
body.push(chunk);
});
res.on('end', function() {
try {
body = JSON.parse(Buffer.concat(body).toString());
}
catch(e) {
console.error(e.message)
reject(e);
}
resolve(body);
});
});
req.on('error', (e) => {
console.error(e);
reject(e)
});
req.write(postData);
req.end();
});
}
try {
data = {firstName: 'Donald', lastName: 'Duck'}
const who = promise_it(data)
who
.then(r => console.info('INFO:',r))
.catch(e => console.error('ERROR:',e));
}
catch (error) {
console.error('FATAL:',error)
}
The function works as expected.
I translated this into an async/await function:
async_it = async (data) => {
if (!data) {throw new Error('data is missing');}
let postData = JSON.stringify(data);
let options = {
hostname: 'httpbin.org',
port: 443,
path: '/post',
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
// Accept: 'application/json'
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
const https = require('https');
let req = https.request(options, (res) => {
let body = [];
res.on('data', function(chunk) {
body.push(chunk);
});
res.on('end', function() {
try {
body = JSON.parse(Buffer.concat(body).toString());
// how do i return the body?
}
catch(e) {
console.error('HERE:',e.message)
throw e;
}
});
});
req.on('error', (e) => {
console.error('THERE:',e.message)
});
req.write(postData);
req.end();
}
(async () => {
try {
data = {firstName: 'Donald', lastName: 'Duck'}
const who = await async_it(data)
console.info('INFO:',who)
}
catch (error) {
console.error('FATAL:',error)
}
})();
But I can't seem to find a way to return the body. What am I missing?
Unfortunately https.request uses the "last parameter callback" Node.js style, so there is no possibility to use it as-is with async/await.
You could make a wrapper like in nodejs - How to promisify http.request? reject got called two times for example, and then you can use it like:
try {
const body = await httpsRequest(options, postData);
return body;
} catch (e) {
console.error('THERE:',e.message);
}
But the mentioned wrapper is not much less than your current one (Promise version).

ENOTFOUND issue on https get request

In my application I'm trying to hit an end point using https and then getting the response.
Route file:
router.get("/get-details", (req, res) => {
sampleController.getDetails()
.then((data) => {
console.log("Data is ", data);
res.send(data);
})
.catch(() => {
res.status(500).json({
success: false,
data: null,
message: "Failed to lookup the data",
});
});
});
Controller file:
const getDetials = () => {
return new Promise((resolve, reject) => {
const options = {
hostname: "https://jsonplaceholder.typicode.com/",
path: "posts",
method: "GET",
};
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
res.on("data", (d) => {
process.stdout.write(d);
});
});
req.on("error", (error) => {
console.log("Error is ", error);
reject(error);
});
req.end();
});
};
I am getting this error:
Not sure where I'm making the mistake. Does somebody know what I'm getting wrong here?
Try setting up the URL without the protocol and add / in front of the path in options object:
const options = {
hostname: "jsonplaceholder.typicode.com",
path: "/posts",
method: "GET",
};
Full example:
const getDetials = () => {
return new Promise((resolve, reject) => {
const options = {
hostname: "jsonplaceholder.typicode.com",
path: "/posts",
method: "GET",
};
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
res.on("data", (d) => {
process.stdout.write(d);
});
});
req.on("error", (error) => {
console.log("Error is ", error);
reject(error);
});
req.end();
});
};

res.json is not a function - nodejs

I've got this error using res.json to get the return of my function and this is code is been used em anothers places as wrote below, running fine.
async function getPlaylist(req, res, playlistId) {
try {
// const calltoken = await getToken()
// const token = calltoken.data.access_token
// console.log(token)
const config = {
headers: {
'Authorization': 'Bearer ' + 'BQA0K9bKgBVn8xTp-yTsoaKs5VfS7EyjMIL03OEOy05wq08ZmLkNfqbbnsL_hFT1AV2FGN5tAQdeDV1X224', //token,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
const url = 'https://api.spotify.com/v1/playlists/1j2L3DjzZ3SdN64r83Sblj?si=cuvOrPONSO6caE9XD6smEg'
await axios.get(url, config)
.then(function (response) {
var playlist = response
var items = playlist.data.tracks.items
// console.log(items)
const playlistfull = []
items.forEach(index => {
var playlistdata = {
name: index.track.name,
artists: index.track.album.artists[0].name,
album: index.track.album.name,
url: index.track.external_urls.spotify
}
playlistfull.push(playlistdata)
})
return res.json(playlistfull)
})
} catch (error) {
return console.log(error)
}
}
You have to use in NodeJS
Node's res give parameter to function
const router = express.Router();
router
.route('/')
.get((req, res) => {
const playlistId = 'asdf';
getPlaylist(req, res, playlistId);
return;
});

javascript promise callback

I am calling a javascript function , which in turn calls a web service;The response of this service is used to call another function which also calls a service. At end of both services we set session attributes. This code gives no errors, but the callback gets called before the service has returned data. The main motive of this code is to set the session attributes before return of flow from this code, when the callback gets called before the service has returned values the session attributes are not set and the requirement of the code is not fulfilled.
'use strict';
function close(sessionAttributes, fulfillmentState, message) {
return {
sessionAttributes,
dialogAction: {
type: 'Close',
fulfillmentState,
message : 'For security purpose answer these questions '
},
};
}
function getSecurityQuestions(intentRequest, context, post_options, callback){
const sessionAttributes = intentRequest.sessionAttributes || {};
var policynumber = sessionAttributes.policynumber;
var interactionID = sessionAttributes.interactionID;
var body = "";
var body2;
const http = require('https');
const promise = new Promise((resolve, reject) => {
const post_data = JSON.stringify({"Purpose":"SecurityQuestions", "InteractionID":interactionID, "SearchStringAcctNum":policynumber});
//ignores SSL
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var post_request = http.request(post_options, function(res) {
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
context.done(body);
resolve(body);
});
res.on('error', function(e) {
reject(Error(e.message));
context.fail('error:' + e.message);
});
});
// post the data
post_request.write(post_data);
post_request.end();
});
callback( promise.then((body) => {
body2 = JSON.parse(body);
sessionAttributes.question1 = body2.SecurityDetails[0].Question;
close(sessionAttributes, 'Fulfilled');
}, (error) => {
console.log(error.message);
})
);
}
function getInteraction(intentRequest, context, callback) {
const slots = intentRequest.currentIntent.slots;
var policynumber = "PA"+slots.PolicyNumber;
var questionOne = slots.questionOne;
var questionTwo = slots.questionTwo;
const sessionAttributes = intentRequest.sessionAttributes || {};
console.log("policy number : "+policynumber + "question 1 : "+questionOne + "question 2 : "+questionTwo);
sessionAttributes.policynumber = policynumber;
var body = "";
var body2;
// An object of options to indicate where to post to
var post_options = {
host: 'example.com',
protocol: 'https:',
port: '3000',
path: '/hiddenPath',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
const http = require('https');
const promise = new Promise((resolve, reject) => {
const post_data = JSON.stringify({"Purpose":"CreateInteraction"});
//ignores SSL
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var post_request = http.request(post_options, function(res) {
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
context.done(body);
resolve(body);
});
res.on('error', function(e) {
console.log("rejected here");
reject(Error(e.message));
context.fail('error:' + e.message);
});
});
// post the data
post_request.write(post_data);
post_request.end();
});
callback( promise.then((body) => {
body2 = JSON.parse(body);
console.log("interaction ID : "+body2.InteractionID);
sessionAttributes.interactionID = body2.InteractionID;
getSecurityQuestions(intentRequest, context, post_options, callback);
}, (error) => {
console.log('Promise rejected.');
console.log(error.message);
}));
}
// --------------- Intents -----------------------
/**
* Called when the user specifies an intent for this skill.
*/
function dispatch(intentRequest, context, callback) {
const intentName = intentRequest.currentIntent.name;
if (intentName === 'currIntent') {
return getInteraction(intentRequest, context, callback);
}
throw new Error(`Intent with name ${intentName} not supported`);
}
// --------------- Main handler -----------------------
function loggingCallback(response, originalCallback) {
console.log("logging callback called......");
originalCallback(null, response);
}
exports.handler = (event, context, callback) => {
try {
dispatch(event, context, (response) => loggingCallback(response, callback));
} catch (err) {
callback(err);
}
};
You should resolve your promise only after the request ends.. Have updated your sample below. Hope it helps. Also, you were sending an invalid object as your post body. Fixed that as well.
function getValue(context, post_options, callback) {
var body = "";
var body2;
const http = require('http');
const promise = new Promise((resolve, reject) => {
// INVALID OBJECT
//const post_data = JSON.stringify({"something"});
const post_data = JSON.stringify({
something: "something"
});
//ignores SSL
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var post_request = http.request(post_options, function(res) {
res.on('data', function(chunk) {
body += chunk;
console.log("inside " + JSON.stringify(body));
// DONT RESOLVE HERE, REQUEST IS NOT COMPLETE
//resolve(body);
});
res.on('end', function() {
context.done(body);
//RESOLVE HERE INSTEAD
resolve(body);
});
res.on('error', function(e) {
reject(Error(e.message));
context.fail('error:' + e.message);
});
});
// post the data
post_request.write(post_data);
post_request.end();
});
promise.then((body) => {
console.log("response data " + JSON.stringify(body));
body2 = JSON.parse(body);
callback(delegate(sessionAttributes, intentRequest.currentIntent.slots));
}, (error) => {
console.log('Promise rejected.');
console.log(error.message);
});
}

How can i respond with JSON with a Lambda function

Below I am trying to repond to a GET with the weather in JSON format. I am attempting the use the const done in order to deliver the response. This does not seem to work. I get the response and weather in console but return nothing to the client.
'use strict';
console.log('Loading function');
const doc = require('dynamodb-doc');
const http = require('http');
const dynamo = new doc.DynamoDB();
function get_json(url, callback) {
http.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
var response = JSON.parse(body);
callback(response);
});
});
}
exports.handler = (event, context, callback) => {
const done = (err, res) => callback(null, {
statusCode: err ? '400' : '200',
body: err ? err.message : JSON.stringify(res),
headers: {
'Content-Type': 'application/json',
},
});
switch (event.httpMethod) {
case 'DELETE':
dynamo.deleteItem(JSON.parse(event.body), done)
break;
case 'GET':
// dynamo.scan({ TableName: event.queryStringParameters.TableName }, done);
done(get_json("http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=92f14e06a6652e81a5a58bd13d152f70", callback, function (resp) {
callback(resp);
}));
break;
}
};
get_json() doesn't return anything, so passing it into done is definitely the wrong thing to do.
It looks like you need to do this:
get_json(
"http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=92f14e06a6652e81a5a58bd13d152f70",
resp => done(null, resp)
);

Categories

Resources