I am trying to fetch a JSON from a remote API using a simple NodeJS HTTP server (it uses request to make HTTP calls). When I run the HTTP response through some JSON validator, it says it's a valid JSON, but I'm not able to manage accessing keys or even keys which are arrays etc.
JSON looks like:
{
"submissions": [{
"token": "db7fa11f970f376cc17c5f8d1760ab98",
"created_at": "2017-03-02T13:01:35Z",
"saved_at": "2017-03-02T12:50:35Z",
"changed_at": "2017-03-02T12:50:35Z",
"email": "",
"data": {
"CompName": "",
"Name": "TestFirma01",
"MA_Name": "Robert Dotzlaff",
"CASFunction": "TestFunktion01",
"CreateDate": "02.03.2017",
"Street1": "TestStrasse",
"Zip1": "12345",
"Town1": "Berlin",
"PhoneFieldStr4": "07225919241",
"MailFieldStr1": "tes#mpl.de",
"Category1": [
"CRM"
],
"Category2": [
"mpl Finance"
],
"gwBranch": [
"B2B",
"B2C"
],
"ITDANZAHLMA": "<25",
"MPLUSERPOT": "<5",
"TurnOver": "<50.000",
"gwBranch_Product": "Maschinen",
"gwBranch_Solution": "Keine",
"Konkurenz": "Nein",
"MPLEINFUEHRUNG1": null,
"MPLEINFUEHRUNG2": [
"> 12 Monate"
],
"MPLEINFUEHRUNG3": "02.03.2017",
"MPLINFRASTRUKTUR1": [
"ERP"
],
"MPLINFRASTRUKTUR2": [
"Lotus"
],
"MPLINFRASTRUKTUR3": [
"RDP-Anbindung"
],
"MPLINTTHEMA1": [
"Projektmanagement",
"Vertrieb"
],
"MPLINTTHEMA2": [
"Auswertungen",
"Zeiterfassung"
],
"MPLINTTHEMA3": [
"Sonstiges"
],
"MPLSONSTIGEINFOS": "Es muss schnell sein",
"MPLKONKPRODUKT": "",
"ANSPR_TEAM": "Robert D",
"ANSPR_Entscheider": "Ptrick R",
"MPLENTSCHEIDUNG": "02.03.2017",
"ITDKLASSIFIZIERUNG": [
"sehr gut"
],
"NEXT_ACTION": [
"Testzugang"
]
},
"attachments": []
}]
}
NodeJS script as follows:
'use strict'
const Hapi = require('hapi');
const Express = require('express');
const Request = require('request');
const Vision = require('vision');
const Handlebars = require('handlebars');
const _ = require('lodash');
const LodashFilter = require('lodash.filter');
const LodashTake = require('lodash.take');
const JSONStream = require('JSONStream');
const jQuery = require('jsdom');
const server = new Hapi.Server();
server.connection({
host: '127.0.0.1',
port: 3000,
routes: {
cors: {
origin: ['*'],
additionalHeaders: ['X-API-KEY']
},
}
});
server.register(Vision, (err) => {
server.views({
engines: {
html: Handlebars
},
relativeTo: __dirname,
path: './views',
});
});
server.start((err) => {
if (err) {
throw err;
}
getJSON();
console.log(`Server running at: ${server.info.uri}`);
});
function getJSON() {
// URL and APIKEY ommitted for security reasons
var as_host = '';
var as_apiKey = ''
var as_endpoint = '/api/public/v1/projects/';
var as_projectId = '736';
var as_endpointExt = '/submissions';
var as_url = as_host + as_endpoint + as_projectId + as_endpointExt;
var options = {
url: as_url,
headers: {
'X-API-KEY': as_apiKey,
},
json: true
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var jsonString1 = JSON.stringify(body);
var jsonObject = JSON.parse(jsonString1);
console.log("BODY2: " + jsonObject);
}
}
Request(options, callback);
}
The console.log("BODY2: " + jsonObject); outputs BODY2: [object Object] which is not what I want. When I remove json: true from the options variable for request, it outputs the JSON (or at least what looks like one), but I am still unable to access key / value pairs in the JSON. I need to access especially the data part of the JSON which contains the relevant data sets that need to be handed over to a second remote REST API (accepts only a special format, which is why I may not simply hand the retrieved JSON over to the other API). I have already tried several solutions and read a lot of posts on here, none of them seems to work for me (JSON.parse(), JSONStream.parse(), _.get() etc). Any help is much appreciated!
Related
I have a user details page in Reactjs where I'm fetching the user details and populating it to the corresponding fields. But I'm not able to access key values from the user object.
My sample code is
function EditProfile(props) {
const [user, setUser] = useState()
useEffect(() => {
const fetchUserInfo = async () => {
const profileConfig = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + auth.token
}
};
fetch(`http://localhost:4000/api/v1/user/me`, profileConfig)
.then(response => response.json())
.then(response => {
console.log("response: ", response.user);
if (response.success === true) {
setUser(response.user)
} else {
alert(response.message)
}
},
(error) => {
alert('User fetching faied: ' + error)
})
}
fetchUserInfo()
}, [])
return (
<div>{user.name}</div>
)
}
The response from the server (user object is)
{
"status": true,
"_id": "5ecfdc403165f709b49a4a0e",
"name": "Anand OL",
"gender": "male",
"dob": "2020-12-13T00:00:00.000Z",
"email": "anand#gmail.com",
"phone": "1234567890",
"createdAt": "2020-05-28T15:44:00.700Z",
"updatedAt": "2020-06-01T08:38:37.902Z",
"__v": 136,
"image": "5ecfdc403165f709b49a4a0e_Image.png"
}
when I try to access name from the user object like user.name
I'm getting an error user is not defined
You need to provide some initial state to display (or conditionally render) while the fetch is occuring.
const [user, setUser] = useState(); // <-- user is undefined!!
Conditionally render UI
return <div>{user && user.name}</div>;
or
return user ? <div>{user.name}</div> : null;
Note: Use caution with the former as not all falsey values are created equal, i.e. Consider return <div>{value && value.property}</div>, if/when value = 0 a falsey value, then a "0" will actually be rendered.
Or you can provide some default state
const [user, setUser] = useState({ name: '' });
I am having issues retrieving and sending results from a MySql database to API.ai. The concrete question is how to wait for the results to be available, and then send the results in the Json object back to API.ai
This is what I have:
In the webhook or service, after receiving the Json request, I call a method:
if (action === 'get.data') {
// Call the callDBJokes method
callDB().then((output) => {
// Return the results to API.AI
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(output));
}).catch((error) => {
// If there is an error let the user know
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(error));
});
}
which calls the method callDB() where the database call is executed:
function callDB() {
return new Promise((resolve, reject) => {
try {
var connection = mysql.createConnection({
host: "127.0.0.1",
user: "root",
password: "x",
database: 'y'
});
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (!error) {
let response = "The solution is: " + results[0].solution;
response = response.toString();
let output = {'speech': response, 'displayText': response};
console.log(output);
resolve(output);
} else {
let output = {'speech': 'Error. Query Failed.', 'displayText': 'Error. Query Failed.'};
console.log(output);
reject(output);
}
});
connection.end();
} catch (err) {
let output = {'speech': 'try-cacth block error', 'displayText': 'try-cacth block error'};
console.log(output);
reject(output);
}
}
);
}
I get a Json response in API.ai like:
{
"id": "5daf182b-009f-4c11-a654-f2c65caa415e",
"timestamp": "2017-08-29T07:24:39.709Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "get data",
"action": "get.data",
"actionIncomplete": false,
"parameters": {},
"contexts": [
{
"name": "location",
"parameters": {
"date": "",
"geo-city": "Perth",
"date.original": "",
"geo-city.original": "perth"
},
"lifespan": 2
},
{
"name": "smalltalkagentgeneral-followup",
"parameters": {},
"lifespan": 2
}
],
"metadata": {
"intentId": "4043ad70-289f-441c-9381-e82fdd9a9985",
"webhookUsed": "true",
"webhookForSlotFillingUsed": "false",
"webhookResponseTime": 387,
"intentName": "smalltalk.agent.general"
},
**"fulfillment": {
"speech": "error",
"displayText": "error",
"messages": [
{
"type": 0,
"speech": "error"**
}
]
},
"score": 1
},
**"status": {
"code": 200,
"errorType": "success"**
},
"sessionId": "c326c828-aa47-490c-9ca0-37827a4e348a"
}
I am getting only the error message but not the result from the database. I read that it could be done using callbacks as well, but I could not figure it out yet. I can see that the database connection is working, because the logs of the connections shows the connection attempts.
Any help will be appreciated. Thanks.
Solved by declaring the var mysql = require('mysql'); as const mysql = require('mysql'); not inside the function, but before the exports.myfunction declaration. Working example code to get results from MySql DB using node.js MySQL, and send them back to API.ai is as follows:
'use strict';
const mysql = require('mysql');
exports.her_goes_your_function_name = (req, res) => { //add your function name
//Determine the required action
let action = req.body.result['action'];
if (action === 'get.data') {
// Call the callDBJokes method
callDB().then((output) => {
// Return the results of the weather API to API.AI
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(output));
}).catch((error) => {
// If there is an error let the user know
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(error));
});
}
};
function callDB() {
return new Promise((resolve, reject) => {
try {
var connection = mysql.createConnection({
host: "127.0.0.1",
user: "your_user",
password: "your_pass",
database: "your_DB"
});
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (!error) {
let response = "The solution is: " + results[0].solution;
response = response.toString();
let output = {'speech': response, 'displayText': response};
console.log(output);
resolve(output);
} else {
let output = {'speech': 'Error. Query Failed.', 'displayText': 'Error. Query Failed.'};
console.log(output);
reject(output);
}
});
connection.end();
} catch (err) {
let output = {'speech': 'try-cacth block error', 'displayText': 'try-cacth block error'};
console.log(output);
reject(output);
}
}
);
}
I have a JSON file that I'm calling into a file:
{
"SecurityGroups": [
{
"IpPermissionsEgress": [],
"Description": "My security group",
"IpPermissions": [
{
"PrefixListIds": [],
"FromPort": 22,
"IpRanges": [
{
"CidrIp": "203.0.113.0/24"
}
],
"ToPort": 22,
"IpProtocol": "tcp",
"UserIdGroupPairs": []
}
],
"GroupName": "MySecurityGroup",
"VPCId": "123456789012",
"GroupId": "sg-903004f8",
}
]
}
My JSON file looks like this:
SyntaxError: /Users/testuser/Documents/testsecuritygroups.json: Unexpected token } in JSON at position 696
at JSON.parse (<anonymous>)
at Object.Module._extensions..json (module.js:588:27)
The error group name and description is clearly there. Not sure why I'm getting these errors. This is what my code looks like:
'use strict';
process.env.AWS_PROFILE
var PropertiesReader = require('properties-reader');
var AWS = require('aws-sdk')
var properties = PropertiesReader('/Users/testuser/.aws/credentials');
AWS.config.update({
accessKeyId : properties.get('aws_access_key_id'),
secretAccessKey : properties.get('aws_secret_access_key'),
region : 'us-east-1'
})
var ec2 = new AWS.EC2({apiVersion: '2016-11-15'});
// Load credentials and set region from JSON file
// Load in security group parameters
let securityParams = require('./securityParams.json');
let securityParamsJSON = JSON.stringify(securityParams);
module.exports = {
//Exports creation of Security Groups
createSecurityGroup: (req, res) => {
ec2.createSecurityGroup(securityParams[0].SecurityGroups[0], function(err, data) {
if (err) {
return (console.log("Error", err));
}
// Pass the Json as a parameter in this function
ec2.authorizeSecurityGroupIngress(securityParams.IpPermissions, function(err, data) {
if (err) {
res.serverError(err, err.stack);
} else {
res.ok(data);
console.log('Ingress Security Rules Created');
}
})
// Pass the Json as a parameter in this function
ec2.authorizeSecurityGroupEgress(securityParams.IpPermissionsEgress[0], function(err, data) {
if (err) {
res.serverError(err, err.stack);
} else {
res.ok(data);
console.log('Egress Security Rules Created');
}
})
})
}
}
module.exports.createSecurityGroup();
I'm just trying to create security groups in AWS through this script.
var request=require('request');
var values = [
{
"id": "24",
"kind": "nature",
"data": {}
}
]
request.put("http://localhost:5000/api/article/",values,function (err,data,res) {
res=JSON.parse(res)
console.log(res)
})
I think it's kinda obvious what I'm trying to do here. Can someone please tell me what I'm doing wrong?? If I'm verry far of can someone set me on the right track?
var request = require('request');
var values = [
{
"id": "24",
"kind": "nature",
"data": {}
}
];
request({
method: 'PUT',
url: 'http://localhost:5000/api/article/',
body: values,
json: true,
headers: {
'User-Agent': 'request'
}
}, (err, res, body) => {
// ...
});
See the docs: https://www.npmjs.com/package/request#custom-http-headers
I'm trying to parse, some json data from an url and save it into my mongoDB model. however i can't seem to parse the JSON correctly from the body. How can i achieve this?
Code
router.get('/news', function(req, res){
request({
method: "GET",
url: "URL",
json: true
}, function(err, response, body) {
console.log(err);
res.json(body);
var info = JSON.parse(body);
console.log(info.articles);
})
});
Snippet of code from the api
{
"articles": [
{
"title": "this is the title",
"created": "12-09-2015",
"author": "John Doe",
"image": "http://url.com/test.jpg",
"body": "this is the body"
},
{
"title": "this is the title",
"created": "12-09-2015",
"author": "John Doe",
"image": "http://url.com/test.jpg",
"body": "this is the body"
}
]
}
News model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var newsSchema = new Schema({
title: String,
created: String,
author: String,
image: String,
bodyfull: String
});
module.exports = mongoose.model('news', newsSchema);
I'm not sure I understand exactly what's going on in your example there.
But if you want to retrieve information from a request body in node, you can from a POST request
so
var News = require('newsModel'); //wherever it's located
Router.post('/news', function(req,res){
var infoToParse = req.body;
var info = JSON.parse(infoToParse);
var newsItem = new News(info);
newsItem.save(function(err){
if(err) return handleError(err)
});
}
not sure if that helps at all? I'm no node guru but that's the kind of thing I do