I am currently trying to get a JSON object out of a function.
I can access all the data in the function, but I am struggling to get the data out so I can actually use the Data.
var imdb = require('imdb');
imdb('tt4477536', function(err, data) {
if(err)
console.log(err.stack);
if(data)
console.log(data)
});
This works fine and I get the Data:
{ title: 'Fifty Shades Freed',
year: '2018',
contentRating: 'R',
runtime: '1h 45min',
description: 'Anastasia and Christian get married, but Jack Hyde
continues to threaten their relationship.',
rating: '4.4',
poster: 'https://images-na.ssl-images-amazon.com/images/M/MV5BODI2ZmM5MzMtOWZiMC00ZGE3LTk3MWEtY2U0ZjE3ZWJlNDEzXkEyXkFqcGdeQXVyMTMxODk2OTU#._V1_UX182_CR0,0,182,268_AL_.jpg',
genre: [ 'Drama', ' Romance', ' Thriller' ],
director: 'James Foley',
metascore: '31',
writer: 'Niall Leonard' }
So now my question is how do I get the Data out of this function, so I can actually use the data somewhere else in the code? like if i need the title in a string?
thanking you in advance.
Thomas
You can just declare a variable outside it:
var imdb = require('imdb');
var imdbData = {};
imdb('tt4477536', function(err, data) {
if(err)
console.log(err.stack);
if(data) {
imdbData = data;
console.log(data);
}
});
But do mind that since this is an asynchronous function you should be using a callback or Promise to be safe when using tha data. For a better approach:
var imdb = require('imdb');
imdb('tt4477536', function(err, data) {
if(err)
console.log(err.stack);
if(data) {
doNext(data);
}
});
function doNext(data) {
//use the data
}
Related
I'm trying to write a JSON object (or string, unsure) to my mysql database using node.js. I first retrieved the JSON via an xml url using xml2js. I am able to log the json string result in my console via JSON.stringify, but I am unsure how to proceed from here.
Here is the url I took the xml from: https://water.weather.gov/ahps2/hydrograph_to_xml.php?gage=deld1&output=xml
I would like to write each instance from the JSON string to a row, with the columns as the name of the data. It would look something like this:
Here is my code in index.js, which I enact with node index.js on the console:
var parseString = require('xml2js').parseString;
var http = require('http');
var https = require('https');
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: "mydb"
});
function xmlToJson(url, callback) {
var req = https.get(url, function(res) {
var xml = '';
res.on('data', function(chunk) {
xml += chunk;
});
res.on('error', function(e) {
callback(e, null);
});
res.on('timeout', function(e) {
callback(e, null);
});
res.on('end', function() {
parseString(xml, function(err, result) {
callback(null, result);
});
});
});
}
var url = "https://water.weather.gov/ahps2/hydrograph_to_xml.php?gage=deld1&output=xml"
xmlToJson(url, function(err, data) {
if (err) {
return console.err(err);
}
strungout = JSON.stringify(data, null, 1);
console.log(strungout);
//strungout contains my json string
})
con.connect(function(err) {
if (err) throw err;
//below is where I might make an insert statement to insert my values into a mysql table
var sql = someinsertstatement
con.query(sql, function (err, result) {
if (err) throw err;
console.log("records inserted");
res.end();
});
});
As mentioned, when I run the above code in my console, the console returns the JSON, though I am unsure how to assign this to a variable that I can then write into my mysql database.
Alternatively, if there is an easier way to write xml from a website directly to my mysql database, I would certainly appreciate any pointers. I feel like it should be easier than this, but I am new to pretty much all of it.
EDIT:
Adding the JSON. I removed the line breaks to consolidate it. Trying to assign the result '4.68' to a variable.
data = {"site": {"observed": [{"datum": [{"valid": [{"_": "2019-02-21T19:42:00-00:00","$": {"timezone": "UTC"}}],"primary": [{"_": "4.68","$": {"name": "Stage","units": "ft"}}]}]}]}};
Thank you.
This worked on my end. Found that the main data you seek is site.observed.datum
const parser = require('xml2json');
const request = require("request");
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: "mydb"
});
var api_url = 'https://water.weather.gov/ahps2/hydrograph_to_xml.php?gage=deld1&output=xml';
function xmlToJson(url, callback){
return request({
method: 'GET',
url: api_url,
}, function (error, response, body) {
if (error) {
return callback({
errorResponse: error,
rowsToInsert: false
});
}else{
let jsonRes = JSON.parse(parser.toJson(body));
let datumResult = jsonRes.site.observed.datum;//I had to log Object.keys multple time to get the
const readyForDB = datumResult.map(x => {
let timeOfReading = x.valid.$t;
let stage = x.primary.$t;
let flow = x.secondary.$t;
return [
timeOfReading, stage, flow
]
});
return callback({
errorResponse: false,
rowsToInsert: readyForDB
});
}
})
}
return xmlToJson(api_url, ({errorResponse, rowsToInsert}) => {
if(errorResponse){
throw callback.errorResponse;
}
return con.connect(function(err) {
if (err) throw err;
//below is where I might make an insert statement to insert my values into a mysql table
var sql = "INSERT INTO forecast (timeOfReading, stage, flow) VALUES ?"
con.query(sql, [rowsToInsert], function (err, result) {
if (err) throw err;
console.log(result.affectedRows + " rows inserted");
});
});
});
Sounds like you have the JSON you want but are unsure how to access data within it. Correct me if I'm wrong.
Lets say you have this JSON object called "test":
{
a:1
b:{
x:2
}
}
You can access the value of 1 by calling test.a, and similarly access the value of 2 by calling test.b.x
I have a JSON read to UI and modifiled as part of review process. Finally I want to save New data to a New folder/File.
Code Sample below - Always ends with POST call in error :
SaveFinalData(){
this.postJson<Reaction>
('./assets/ICP/Reviewed/Json/out.json',
this.reactionDatabase.reactiondataChange.value);
}
postJson<Reaction>(url: string, Reaction: any){
//let body = JSON.stringify({ Reaction });
this.http.post(url, body)
.subscribe(
(val) => {
console.log("POST call successful value returned in body", val);
},
response => {
console.log("POST call in error", response);
},
() => {
console.log("The POST observable is now completed.");
});
}
Have tried below 2 alternatives:
(1)
var theJSONdata = JSON.stringify({ Reaction });
window.localStorage.setItem('./assets/ICP/Reviewed/Json/out.json', theJSONdata)
Result -- NO LUCK!
(2)
var jsonfile = require('jsonfile')
var file = './assets/ICP/Reviewed/Json/out.json'
var obj = {name: 'JP'} //SAMPLE DATA
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
Result -- NO LUCK! --> GIVES ERROR fs.writeFile is not a function
Pls kindly help/guide me to reach the final result....Thanks
Hi Guys I want to know how to save json string into mongoose model object?
let me explain a simplified version of my problem:
I have a schema model:
const mongo = require('mongoose');
const clientSchema = mongo.Schema({
name: {type: String},
age: {type: Number},
updated_at: {type: Date},
}
and I have a put method which is shown below:
var Client = mongo.model('client', clientSchema);
//Update User
server.put(`/api/clients/:_id`, (req, res) =>
{
Client.model.findById(req.params._id, (err, foundedclient) =>
{
if(err) res.send(err);
//***********************************************************//
/*I want to update foundedclient from req.body here! */
/*some function like : foundedclient.JsonTovalues(req.body); */
//***********************************************************//
foundedclient.updated_at = new Date().toISOString();
foundedclient.save((err) =>
{
res.send('saved successfully!');
});
});
});
the req.body is a json:
{
"name":"bardia",
"age":27,
}
I want to update foundedclient value from req.body at the position I highlighted in the code by //*******// signs. I want a hypothetical function such as foundedclient.JsonTovalues(req.body). what is the best way to achieve that? In other words what is the best way to save json as mode values?
Thank a lot
you can define an instance method to something similar to updateByJson as explained below
const clientSchema = mongo.Schema({
name: {type: String},
age: {type: Number},
updated_at: {type: Date},
}
// here simply calling update method internally but exposed as an instance method
clientSchema.methods.updateByJson = function(jsonToUpdate, cb){
// will work if you are using mongoose old version 3.x
this.constructor.update({_id: this._id}, {$set:jsonToUpdate}, cb);
// should work with latest versions
this.model('client').update({_id: this._id}, {$set:jsonToUpdate}, cb);
}
Your client code will look like this
var Client = mongo.model('client', clientSchema);
//Update User
server.put(`/api/clients/:_id`, (req, res) =>
{
Client.model.findById(req.params._id, (err, foundedclient) =>
{
if(err) res.send(err);
jsonToUpdate = req.body
jsonToUpdate.updated_at = new Date().toISOString();
foundedclient.updateByJson(jsonToUpdate, (err) => {
res.send('saved successfully!');
});
});
});
I hope this helps you.
What's the best approach to streaming MongoDB query responses to the client via Hapi? I've seen some examples with http or request, but not hapi.
The problem is that I'm getting concatenated and stringified JSON objects on the client side, but I can't can't call JSON.parse on the result because together it's not valid JSON.
Some solutions I've seen suggest concatenating on the server side before sending to the client, but that seems to defeat the value of streams.
For example:
const Hapi = require('hapi'),
MongoClient = require('mongodb').MongoClient,
Readable = require('stream').Readable;
// Connection url
const url = 'mongodb://localhost:27017/test';
// Create a server with a host and port
const server = new Hapi.Server();
server.connection({
host: 'localhost',
port: 8000
});
// Add the route
server.route({
method: 'GET',
path: '/stream',
handler: function (request, reply) {
let docs = [{ a: 1, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 3 }, { a: 4, b: 4 }];
// Connect using MongoClient
MongoClient.connect(url, (err, db) => {
// Create a collection we want to drop later
const col = db.collection('stream_example');
// Insert documents into collection
col.insertMany(docs, { w: 1 }, function (err) {
if (err) return console.log(err);
// Peform a find to get a cursor
const stream = col.find()
.stream({
transform: function (doc) {
return JSON.stringify(doc);
}
});
reply(new Readable().wrap(stream));
});
});
}
});
// Start the server
server.start(err => {
if (err) {
throw err;
}
console.log('Server running at:', server.info.uri);
});
Returns a response.result of:
"{"_id":"57b0b99d681bb97a9321f03e","a":1,"b":1}{"_id":"57b0b99d681bb97a9321f03f","a":2,"b":2}{"_id":"57b0b99d681bb97a9321f040","a":3,"b":3}{"_id":"57b0b99d681bb97a9321f041","a":4,"b":4}"
Which is not valid JSON and cannot be parsed.
I've tried piping this stream into the event-stream module's .join('\n') stream to add newlines while also pushing string'd "[" and "]" before and after to build a stringified JSON Array, but have not yet been successful. This feels too hacky anyways.
Is there a better way?
A valid JSON has to be sent by using a stream transform.
Basically you have to:
start the stream with '['
then append stringified JSON object
add ',' after each of the objects
end stream with ']'
so the final result recevied in the stream would be valid JSON, like
[
{'key': 'value'},
{'key': 'value'},
]
Some of the solutions:
http://andyfiedler.com/2017/01/mongodb-stream-to-hapi
https://github.com/nlindley/hapi-mongo-stream
https://github.com/dominictarr/JSONStream
Here is an example of how I have been using Mongo with Hapi.
From BoardRepo.js:
module.exports = {
GetAllBoards: function (facility) {
return new Promise(function (resolve, reject) {
var db = mongo.ETestDatabase;
db.collection('boards').find({ "Location.Facility": facility }).toArray().then(r => {
resolve(r);
}).catch(err => {
logger.error('Error getting all boards by facility - ' + err.message);
reject(err.message);
});
});
}
};
In the Hapi handler (BoardHandler.js):
module.exports = {
GetAllBoards: {
method: 'GET',
path: '/v1/boards/facility/all/{facility}',
config: {
auth: 'jwt',
plugins: { 'hapiAuthorization': { roles: ['ADMINISTRATOR', 'MANAGER', 'TECHNICIAN', 'OPERATOR'] } },
description: 'Gets all boards per facility',
tags: ['api'],
handler: (request, reply) => {
logger.info('[' + request.auth.credentials.username + '] GetAllBoards requested');
var facility = request.params.facility;
repo.GetAllBoards(facility)
.then(boards => {
if (boards !== null) {
reply(boards);
} else {
reply().code(404);
}
})
.catch(err => {
geh.HandleError(request.auth.credentials.username, err, reply);
});
}
}
}
};
Wanted to see if I could make a bot (just for myself, not to spam. Obviously!) and took the following steps:
Download Node.js from the main site.
Created an app on Twitter and all that stuff.
Tried it a ton of ways and then read this blog: http://www.apcoder.com/2013/10/03/twitter-bot-20-minutes-node-js/
Now, I am here: https://github.com/ttezel/twit I installed it from the terminal and got back:
node_modules/twit
└── oauth#0.9.9
Then I went to include the following (with my Twitter app details included) and got pages and pages of errors. I checked on ShellCheck and it's mostly parsing errors. But as it was just copy and paste, I think I must be doing something else wrong.
Any ideas?
var Twit = require('twit')
var T = new Twit({
consumer_key: '...'
, consumer_secret: '...'
, access_token: '...'
, access_token_secret: '...'
})
//
// tweet 'hello world!'
//
T.post('statuses/update', { status: 'hello world!' }, function(err, data, response) {
console.log(data)
})
//
// search twitter for all tweets containing the word 'banana' since Nov. 11, 2011
//
T.get('search/tweets', { q: 'banana since:2011-11-11', count: 100 }, function(err, data, response) {
console.log(data)
})
//
// get the list of user id's that follow #tolga_tezel
//
T.get('followers/ids', { screen_name: 'tolga_tezel' }, function (err, data, response) {
console.log(data)
})
//
// retweet a tweet with id '343360866131001345'
//
T.post('statuses/retweet/:id', { id: '343360866131001345' }, function (err, data, response) {
console.log(data)
})
//
// destroy a tweet with id '343360866131001345'
//
T.post('statuses/destroy/:id', { id: '343360866131001345' }, function (err, data, response) {
console.log(data)
})
//
// get `funny` twitter users
//
T.get('users/suggestions/:slug', { slug: 'funny' }, function (err, data, response) {
console.log(data)
})
//
// post a tweet with media
//
var b64content = fs.readFileSync('/path/to/img', { encoding: 'base64' })
// first we must post the media to Twitter
T.post('media/upload', { media: b64content }, function (err, data, response) {
// now we can reference the media and post a tweet (media will attach to the tweet)
var mediaIdStr = data.media_id_string
var params = { status: 'loving life #nofilter', media_ids: [mediaIdStr] }
T.post('statuses/update', params, function (err, data, response) {
console.log(data)
})
})
//
// stream a sample of public statuses
//
var stream = T.stream('statuses/sample')
stream.on('tweet', function (tweet) {
console.log(tweet)
})
//
// filter the twitter public stream by the word 'mango'.
//
var stream = T.stream('statuses/filter', { track: 'mango' })
stream.on('tweet', function (tweet) {
console.log(tweet)
})
//
// filter the public stream by the latitude/longitude bounded box of San Francisco
//
var sanFrancisco = [ '-122.75', '36.8', '-121.75', '37.8' ]
var stream = T.stream('statuses/filter', { locations: sanFrancisco })
stream.on('tweet', function (tweet) {
console.log(tweet)
})
//
// filter the public stream by english tweets containing `#apple`
//
var stream = T.stream('statuses/filter', { track: '#apple', language: 'en' })
stream.on('tweet', function (tweet) {
console.log(tweet)
})