Reading values from JSON in Node.js in GET request - javascript

I need to pull the Indication value from the following
{
"records": [{
"id": "recBgV3VDiJeMkcwo",
"fields": {
"DrugName": "azatadine",
"nameapi": ["recBgV3VDiJeMkcwo"],
"Indication": "For the relief of the symptoms of upper respiratory mucosal congestion in perennial and allergic rhinitis, and for the relief of nasal congestion and eustachian t.b. congestion.",
"lookup": ["azatadine"],
"drugID": "recBgV3VDiJeMkcwo"
},
"createdTime": "2018-11-09T19:38:24.000Z"
}]
}
When I try to do
response.records[0].fields.Indication
I get the error
Cannot read property 'fields' of undefined
Here is my code:
function httpGet() {
return new Promise(((resolve, reject) => {
var options = {
host: 'api.airtable.com',
port: 443,
path: '/v0/appYqfJ3Rt2F0sRGn/Database?filterByFormula=(DrugName=%27azatadine%27)',
method: 'GET',
headers: {
Authorization: 'Bearer key123456789'
}
};
const request = https.request(options, (response) => {
response.setEncoding('utf8');
let returnData = '';
response.on('data', (chunk) => {
returnData += chunk;
});
response.on('end', () => {
resolve(returnData);
});
response.on('error', (error) => {
reject(error);
});
});
request.end();
}));
}
const UserReplyIntent_Handler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'UserReplyIntent' ;
},
async handle(handlerInput) {
const response = await httpGet();
console.log(response);
return handlerInput.responseBuilder
.speak("Okay. Here we go" + response.records[0].fields.Indication)
.reprompt("say again")
.getResponse();
},
};

Your JSON isn’t really JSON yet at this stage. You need to parse the result you get from your Ajax request to then work with it as native JSON.
The response is stringified when it gets delivered to you, that parse command will in stringify it for you.
You can do this as part of a then chain after your promise (probably best practice) or do it right inside your promise.

I was missing json.parse
.then((response) => {
const data = JSON.parse(response);
for (let i = 0; i < data.records.length; i++) {
if (i === 0) {
outputSpeech = outputSpeech + 'The name of the drug is' + data.records[i].fields.DrugName + ', '

I was missing the json.parse method
.then((response) => {
const data = JSON.parse(response);
for (let i = 0; i < data.records.length; i++) {
if (i === 0) {
outputSpeech = outputSpeech + 'The name of the drug is' + data.records[i].fields.DrugName + ', '

A standard way to do this with asynchronous responses is to do the following:
.then((response) => response.json())
.then((response) => {
//response is now a JSON object that you can be worked with
})

Related

Fetch always returns 200 even when server returns 400 or some error. How to get correct result?

The bounty expires in 2 days. Answers to this question are eligible for a +100 reputation bounty.
Ganesh Putta is looking for an answer from a reputable source.
I have below function in frontend, I have to make some api call here in this function. When i checked the called function via command prompt, the server api call returns 400. but the function in frontend fetch always returning 200 instead of error.
Thanks in advance.
Please guide to how to correct response which is thrown from server call?
Here is the frontend function.
function processFile() {
var fileToLoad = document.getElementById("fileToLoad").files[0];
var url;
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent) {
var rows = fileLoadedEvent.target.result.split("\n");
for (var i = 0; i < rows.length - 1; i++) {
var cells = rows[i].split(",");
//alert(cells);
console.log("AgentteamID=" + cells[0] + " SkilltargetID=" + cells[1] + " flag=" + cells[2]);
url = "/updateAgentTeam?agentTeamID=" + cells[0] + "&skillTargetID=" + cells[1] + "&flag=" + cells[2],
//alert(url);
console.log("URL=" + url);
const response = fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
}).then(response =>
response.json().then(data => ({
data: "success",
status: response.status
})).then(res => {
var statusCode = JSON.stringify(res.status);
//$('#Success_comment').html(JSON.stringify(res)+"---"+url;);
//alert(url);
document.getElementById("Success_comment").value += JSON.stringify(res) + "---" + url;
console.log("final result " + JSON.stringify(res) + "---" + url);
}))
}
}
fileReader.readAsText(fileToLoad, "UTF-8");
}
Here is the Server side code. For now we are using only Flag A block
app.get("/updateAgentTeam", (req, res) => {
var skillTargetID = req.query.skillTargetID;
console.log("req.query.skillTargetID =" + req.query.skillTargetID);
var agentTeamID = req.query.agentTeamID;
var flag = req.query.flag;
var finalurl = "http://198.18.133.11/unifiedconfig/config/agentteam/" + agentTeamID;
var xml;
//console.log("finalurl ="+finalurl);
axios({
url: finalurl,
method: "get",
auth: {
username: "xxx",
password: "yyy"
},
})
.then(async(response) => {
xml = response.data;
//console.log("after calling xml is "+JSON.stringify(xml));
res.send(response.data);
if (flag === 'D') {
agentremovedXML = removeAgentFromXML(xml, skillTargetID);
//newxml=removeAgentFromXML(xml);
//console.log("Final Agent remove XML "+JSON.stringify(agentremovedXML));
postAgentToTeam(agentTeamID, agentremovedXML);
//setSuccessJSON();
} else if (flag === 'A') {
AgentXML = await generateAgentXML(skillTargetID);
console.log("Returned agent xml is " + JSON.stringify(AgentXML));
console.log("xml where agent to be add " + JSON.stringify(xml));
if (JSON.stringify(xml.agentCount) == 0) {
AgentXML = {
"agent": [AgentXML]
};
xml.agents = [AgentXML];
console.log("xml with zero agents " + JSON.stringify(xml));
} else {
xml.agents[0].agent.push(AgentXML);
console.log("Compare " + JSON.stringify(xml));
}
console.log("xml send to postAgentToTeam is " + xml);
postAgentToTeam(agentTeamID, xml);
//postAgentToTeam(agentTeamID,agentXML);
}
})
.catch((err) => {
res.status(400);
res.send(err.response.status);
console.log(err);
//setErrorJSON()
});
});
async function postAgentToTeam(agentTeamID, xml) {
var teamurl = "http://198.18.133.11/unifiedconfig/config/agentteam/" + agentTeamID;
//console.log("final XML is "+JSON.stringify(xml));
xml.agents = xml.agents[0].agent.map(agent => ({
agent: agent
}));
var updatedJSONwithAgentTags = JSON.stringify(xml, null, " ");
//console.log("newwwwwwwwwwwwwwwwwwwwww "+ updatedJSONwithAgentTags);
//return;
js2xml = json2xml(JSON.parse(JSON.stringify(xml)));
json2 = "<agentTeam>" + js2xml + "</agentTeam>";
//console.log("newwww converted XML "+json2);
response = await axios({
url: teamurl,
method: "put",
auth: {
username: "administrator#dcloud.cisco.com",
password: "C1sco12345"
},
data: json2,
headers: {
'Content-Type': 'application/xml; charset=utf-8'
}
})
.then(response => {
console.log("hellooo " + response.status);
})
.catch((err) => {
console.log(err.response.data.apiError);
console.log("error res is " + err.response.status);
});
}
There's a quite few things wrong.
Inside your first .then(async(response) => {, you set the xml to response.data then right away call res.send(response.data) (200) which is the end of the execution order for Express. However, you go on to do a bunch of other things after the res.send (200) is sent. You should not do that.
You need to restructure your code. Starting from the top-down keeping in mind that all promises need to be returned and that res.send() is the end of the block. Throwing a 400 after this won't matter since Express already sent the response to the client.
You're also mutating theresponse output from Axios which is bad practice. Create a new one if you need to mutate it:
const newResponse = { ...response };
Additionally, this mixing of .then().catch() with an initial await is not how you should handles promises and would cause problems.
Don't write them like this:
response = await axios({}).then().catch().
Either do this:
axios({ // <--- no await, no let response =
url: finalurl,
method: "get",
auth: {
username: "xxx",
password: "yyy"
},
})
.then(async(response) => {
// res.send, etc.
}).catch((e) => {
// handle errors
});
Or use try / catch blocks like this:
try {
const results = await axios({
url: teamurl,
method: "put",
auth: {
username: "administrator#dcloud.cisco.com",
password: "C1sco12345"
},
data: json2,
headers: {
'Content-Type': 'application/xml; charset=utf-8'
}
}); // <--- the end.
console.log({results});
} catch (e) {
// handle errors
console.log(e);
}

how to resolve 'NodeJS API call response is an un-parsable object'?

I am getting the below result after my API call.
My node version is 12.x
{"type":"Buffer","data":[123,34,101,114,114,111,114,115,34,58,91,34,74,87,84,32,105,115,32,101,120,112,105,114,101,100,32,111,114,32,100,111,101,115,32,110,111,116,32,104,97,118,101,32,112,114,111,112,101,114,32,39,101,120,112,39,32,99,108,97,105,109,34,93,125,11]}
Please see the code snippet below:
let postOptions = {
host: 'vault.server',
path: '/v1/auth/gcp/login',
method: HTTPS.POST_REQUEST,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Vault-Namespace': 'mynamespace'
},
json: true,
rpDefaults: {
strictSSL: false
}
};
let requestPayLoad = {
"role": this._vaultRole,
"jwt": signedJWT
};
console.log(JSON.stringify(requestPayLoad));
console.log(JSON.stringify(postOptions));
try {
let result = await HTTPS.makeRequest(postOptions, JSON.stringify(requestPayLoad), HTTPS.POST_REQUEST);
console.log('Response***************',JSON.stringify(result));
return result.auth.client_token;
}
Please see the below code snippet for the http make request method.
return new Promise((resolve, reject) => {
let rq = https.request(options, (res) => {
let response;
let chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
response = Buffer.concat(chunks);
return resolve(response);
});
});
rq.on('error', (e) => {
return reject({'statusCode': 500, 'success': false, 'error': e.toString()});
});
if (type === 'POST') {
rq.write(data);
}
rq.end();
});
Please help me to resolve this
You are receiving the data as a Buffer. Use the toString() method to convert this buffer into a string inside the try block.
try {
let result = await HTTPS.makeRequest(postOptions, JSON.stringify(requestPayLoad), HTTPS.POST_REQUEST);
console.log('Response***************', result.toString());
return result.auth.client_token;
}
If you want to access the data from the response returned from you API call
do:
let data = result.data;
and I you want to get client_token as showing here:
return result.auth.client_token;
it's not possible because the response does not have auth attribute on it:
{"type":"Buffer","data":[123,34,101,114,114,111,114,115,34,58,91,34,74,87,84,32,105,115,32,101,120,112,105,114,101,100,32,111,114,32,100,111,101,115,32,110,111,116,32,104,97,118,101,32,112,114,111,112,101,114,32,39,101,120,112,39,32,99,108,97,105,109,34,93,125,11]}

How to accept a POST request from the Node.js web application.js and return a response?

I can't understand what the problem is, the essence of this request is to pass some data, call a function and send back the generated Json file, but this does not happen, instead the server does not return anything. What could be the problem? Please help me
Web part
clickOnRow: function(elem, whichScreen){
this.clicks++
if(this.clicks === 1) {
var self = this
this.timer = setTimeout(function() {
console.log("одинарный");
self.clicks = 0
}, this.delay);
} else{
clearTimeout(this.timer);
console.log("двойной");
elem['whichScreen'] = whichScreen;
console.log(this.helper);
// this.nameOfMethod(elem);
this.clicks = 0;
fetch('/currentDir1',{
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(elem)
})
.then(response => response.json())
.then(json => this.helper = json)
.then(json => this.$emit("newvalue", json))
console.log("helper");
console.log(this.helper);
Server part
router.post('/currentDir1',(req, req) =>{
console.log("POST");
let body = "";
let pathToFile = "";
req.on("data", function (data) {
body += data;
});
req.on("end", function(currentData) {
console.log(JSON.parse(body));
currentData = JSON.parse(body);
if(currentData.sizeOrType === "<папка>"){
let dir = currentData.dir + currentData.fileName;
// dir = "C:\\totalcmd";
console.log(dir);
if(currentData.whichScreen){
foo(dir, './data/firstScreen.json');
pathToFile = './data/firstScreen.json';
res.sendFile(path.resolve('./data/firstScreen.json'));
}else{
console.log('aaaa');
Foo(dir, './data/secondScreen.json');
pathToFile = './data/firstScreen.json';
res.sendFile(path.resolve('./data/secondScreen.json'));
}
}
// res.json({ message: 'goodbye'})
res.json(path.resolve(pathToFile));
});
res.sendFile(path.resolve(pathToFile));
})

Reading value from JSON array in Node.js during Get request

I need to pull the Indication value from the following array
{
"records": [{
"id": "recBgV3VDiJeMkcwo",
"fields": {
"DrugName": "azatadine",
"nameapi": ["recBgV3VDiJeMkcwo"],
"Indication": "For the relief of the symptoms of upper respiratory mucosal congestion in perennial and allergic rhinitis, and for the relief of nasal congestion and eustachian t.b. congestion.",
"lookup": ["azatadine"],
"drugID": "recBgV3VDiJeMkcwo"
},
"createdTime": "2018-11-09T19:38:24.000Z"
}]
}
When I try to do response.records.fields[0]["Indication"] I get undefined.
Here is my full code:
function httpGet() {
return new Promise(((resolve, reject) => {
var options = {
host: 'api.airtable.com',
port: 443,
path: '/v0/appYqfJ3Rt2F0sRGn/Database?filterByFormula=(DrugName=%27azatadine%27)',
method: 'GET',
headers: {
Authorization: 'Bearer key123456789'
}
};
const request = https.request(options, (response) => {
response.setEncoding('utf8');
let returnData = '';
response.on('data', (chunk) => {
returnData += chunk;
});
response.on('end', () => {
resolve(returnData);
});
response.on('error', (error) => {
reject(error);
});
});
request.end();
}));
}
const UserReplyIntent_Handler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'UserReplyIntent' ;
},
async handle(handlerInput) {
const response = await httpGet();
console.log(response);
return handlerInput.responseBuilder
.speak("Okay. Here we go" + response.records[0].fields.Indication)
.reprompt("say again")
.getResponse();
},
};
Thanks in advance for your help.
it should be response.records[0].fields.Indication
Fields doesn't look like an array. Try response.records.fields.Indication
Show console.log(response) output. Looks like that you made a mistake in getting a response

Not getting data after dependent api call using async problem node

I am calling API to fetch data on the basis of that data I am calling different APIs which is based on condition.
I have used a promise to maintain the async code as well but no luck so far. At the end of the block, I want every data pushed inside array but I am getting a blank array.
async (body, nextCall) => {
var tmpArryOfModuleList = []
var bodyData = body.data
var promise = new Promise((resolve, reject) => {
bodyData.forEach(element => {
if (element.hasCRUD === '0') {
var options = {
method: 'GET',
url: `${apiURL}/api/fetchAllCharts`,
headers:
{
Authorization: token
}
};
request(options, function (error, response, dashboardData) {
if (error) {
return nextCall({
error: error
})
}
var parsedDashboardData = JSON.parse(dashboardData)
for (var i = 0; i < parsedDashboardData['data'].length; i++) {
var val = element.name + " - " + parsedDashboardData['data'][i]['name']
var randomID = Math.random().toString(36).slice(2)
tmpArryOfModuleList.push({ "_id": randomID, "submodule": val })
}
});
} else if (element.hasCRUD == '1') {
var options = {
method: 'GET',
url: `${apiURL}/api/fetchAllActions`,
headers:
{
Authorization: token
}
};
request(options, function (error, response, crudData) {
if (error) {
return nextCall({
error: error
})
}
var parsedcrudData = JSON.parse(crudData)
for (var i = 0; i < parsedcrudData['data'].length; i++) {
var val = element.name + " - " + parsedcrudData['data'][i]['name']
var randomID = Math.random().toString(36).slice(2)
tmpArryOfModuleList.push({ "_id": randomID, "submodule": val })
}
});
} else {
console.log('no data found')
reject('No Data Found')
}
})
resolve(tmpArryOfModuleList)
})
console.log('tmpArryOfModuleList', tmpArryOfModuleList)
}
What am I doing wrong? How can I achieve the result on the last array?

Categories

Resources