so I'm learning NodeJS and javascript in general, and playing around with it and I have some problems parsing a JSON. I receive the following from the "user":
{
"sync_contact_list": [
{
"name": "c",
"number": "789",
"email": ""
},
{
"name": "b",
"number": "123",
"email": "a#a.com"
},
{
"name": "a",
"number": "416",
"email": ""
}
]
}
My question is how can i properly parse this to get the individual bits:
{
"name": "a",
"number": "416",
"email": ""
}
I've been trying to do it by doing var jsonObject = JSON.parse(req.body); ,but I keep getting parsing errors, no matter how I vary the JSON that I do receive (individual components, all of it, etc).
Could anyone one point out what I'm doing wrong?
EDIT:
So i use express to deal with the different paths. So i have app.js:
var express = require('express')
, routes = require('./routes')
//var mysql = require('mysql');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
//app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
//app.post('/', routes.syncServiceIndex);
app.post('/syncService', routes.synchServicePost);
app.get('/syncService/:syncServiceUser/sync', routes.synchServiceSync);
app.post('/syncService/:syncServiceUser/push', routes.synchServicePush);
app.del('/syncService/:syncServiceUser', routes.synchServiceDel);
app.post('/syncService/:syncServiceUser/contacts/push', routes.synchServiceContactsPush);
app.get('/syncService/:syncServiceUser/contacts/sync', routes.synchServiceContactsSync);
app.post('/syncService/:syncServiceUser/contacts/', routes.synchServiceContactsPost);
app.get('/syncService/:syncServiceUser/contacts/:contactId', routes.synchServiceContactsGet);
app.put('/syncService/:syncServiceUser/contacts/:contactId', routes.synchServiceContactsPut);
app.del('/syncService/:syncServiceUser/contacts/:contactId', routes.synchServiceContactsDel);
app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
And then I have index.js, where I basically have the following for each route.
exports.synchServicePost = function(req, res) {
console.log('synchServicePost');
console.log("BODY:"+JSON.stringify(req.body));
var jsonObject = JSON.parse(req.body);
res.statusCode = 200;
res.send("OK\n");
}
The request is made with a line free JSON:
curl -i -d "{'sync_contact_list':[{'name':'c','number':'789','email':''},{'name':'b','number':'123','email':'a#a.com'},{'name':'a','number':'416','email':''}]}" http://localhost:3000/syncService
EDIT: I realized I should probably change the Content Type to application/json. in this case, for JSON.stringify I get the following:
SyntaxError: Unexpected token ILLEGAL
at parse (native)
at IncomingMessage.<anonymous> (/home/alex/peekcode/quipmail/synch/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:71:15)
at IncomingMessage.emit (events.js:61:17)
at HTTPParser.onMessageComplete (http.js:133:23)
at Socket.ondata (http.js:1029:22)
at Socket._onReadable (net.js:677:27)
at IOWatcher.onReadable [as callback] (net.js:177:10)
Maybe it is already parsed? I do not know (I did not see your whole code).
If it is (or you will parse it the way you need), then specific "bits" will be available like that (see this jsfiddle for a proof):
for (var i=0; i<jsonObject['sync_contact_list'].length; i++){
// here jsonObject['sync_contact_list'][i] is your current "bit"
}
Within the loop, between iterations, jsonObject['sync_contact_list'][i] changes between the "bits", because i changes and points to the first element, then to the second, and so on, until the last element.
So it turns out my JSON was badly formatted. Bad habit I got from working on a Java project. Once that part was fixed, my request was getting parsed by default, which caused some other headache until I found out about node-inspector.
As a result, I'm selecting Tadeck as having the right answer.
for(count in sync_contact_list) {
console.log('individual json objects list', JSON.stringify(sync_contact_list[count]));
}
Related
I'm new to JavaScript and I'm trying to learn how to build REST API's from a local server on my computer. When I test the GET request on Postman, however, it always comes back with an error: Could Not Get Any Response.
The purpose of the REST API is to (a) Store basic information about the planets in the solar system, (b) allow GET requests and (c) allow me to use POST to add more entries in the database.
When I go to postman I use the following URL: localhost:8000/planets
I'm using mongodb and mongoose. I assume the problem is somewhere in my code because I'm not getting a response from the Server but I can't pinpoint where the problem is. Thanks.
var express = require('express');
var bodyParser = require('body-parser');
var _ = require('lodash');
var mongoose = require('mongoose');
var app = express();
app.use(express.static('planet_pages'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json);
mongoose.Promise = global.Promise;
var promise = mongoose.connect('mongodb://localhost/planet_server', {
useMongoClient: true,
});
promise.then(function(db){
console.log('DATABASE CONNECTED!!');
}).catch(function(err){
console.log('CONNECTION ERROR', err);
});
var Schema = mongoose.Schema;
var planetSchema = new Schema({
name: String,
position: String,
moons: String,
diameterInKm: String,
daysInYear: String,
temperature: String
})
var Planet = mongoose.model('Planet', planetSchema);
Planet.collection.drop();
//*****RAW DATA*****
var planets = [{
name: "Mercury",
position: "Mercury is the first planet from the Sun",
moons: "Mercury has no moons",
diameterInKm: "Mercury's diameter is 4,879km",
daysInYear: "A year on Mercury lasts just 88 days!",
temperature: "The temperature on Mercury is a scorching 427C"},
{ name: "Venus",
position: "Venus is the second planet from the Sun",
moons: "Venus has no moons",
diameterInKm: "Venus's diameter is 12,104km",
daysInYear: "A year on Mercury lasts 225 days!",
temperature: "The temperature on Mercury is 467C. Hot enough to melt lead!"
}];
//*****END OF RAW DATA*****
app.get('/planets', function(req, res){
Planet.find({}).exec(function(err, planets){
if(err) {
return res.status(500).send(err);
}
return res.json(planets);
});
});
app.listen(8000, function(){
console.log('I am listening');
});
EDIT: in the line app.use(express.static('planet_pages'), planet_pages is a folder inside my project folder which contains a couple of HTML pages that I hope to use to make AJAX queries.
Also, supplementary question, in the line app.get('/planets', function(req, res) I'm using /planets as the extension because that's the name of the URL that holds my data in the //*****RAW DATA section. I got this from following a tutorial but I'm not sure why I'm supposed to do it. If anyone could explain this I'd MASSIVELY appreciate it. Thanks.
Also I was advised to use the Planet.collection.drop() to ensure the database refreshes properly when I re-load or make a change to the database. Since I can't even make the GET request work, I'm not sure if I need this line.
Also, I've not put the POST request code in yet because I don't see the point until I can get the GET request function working.
Try commenting out app.use(bodyParser.json)
Hello i have a little problem, i developped a script sftp client with node js that connect to an sftp server and grab some files, i tested it with my local server its working, but when i tried to use it with production server i received this error :
Error: Handshake failed: no matching key exchange algorithm
i already generated the rsa key using ssh-keygen
here is the relevant part of the script :
var Client = require('ssh2').Client;
var fs = require('fs');
var path = require('path');
var args = process.argv.slice(2);
var connSettings = {
host: args[0] || '127.0.0.1',
port: args[1] || 22,
username: args[2] || 'karim',
password: args[3] || 'karimos',
algorithms: {
hmac: ['hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1', 'hmac-sha1-96']
}
};
I also had the same problem and solved it by adding the following:
algorithms: {
kex: [
"diffie-hellman-group1-sha1",
"ecdh-sha2-nistp256",
"ecdh-sha2-nistp384",
"ecdh-sha2-nistp521",
"diffie-hellman-group-exchange-sha256",
"diffie-hellman-group14-sha1"
],
cipher: [
"3des-cbc",
"aes128-ctr",
"aes192-ctr",
"aes256-ctr",
"aes128-gcm",
"aes128-gcm#openssh.com",
"aes256-gcm",
"aes256-gcm#openssh.com"
],
serverHostKey: [
"ssh-rsa",
"ecdsa-sha2-nistp256",
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp521"
],
hmac: [
"hmac-sha2-256",
"hmac-sha2-512",
"hmac-sha1"
]
}
For myself, I added debug: console.log to my config object. This output more about the connection attempt.
{
"port": 22,
"host": "test.test.com",
"user": "test",
"password": "******",
"debug": console.log
}
Handshake: (remote) KEX method: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1
Handshake: No matching key exchange algorithm
Based on this error I updated my config's algorithm:
{
"port": 22,
"host": "test.test.com",
"user": "test",
"password": "******",
"algorithms": {
"kex": [
"diffie-hellman-group14-sha1","diffie-hellman-group-exchange-sha1"
]
}
}
After adding this algorithm the connection was successful on my machine
You may edit your /etc/ssh/sshd configuration file, on your server, in order to allow the key authentication method :)
My first suggestion would be to upgrade the ssh server on the server you're connecting to so that a more secure configuration can be had. This is the best/most secure solution.
If you cannot make changes on this server and you absolutely need to connect, then you can explicitly set the kex to a list of key exchange methods you want to support (valid algorithm names can be found in the ssh2-streams documentation). For example:
algorithms: {
kex: [ ... ]
}
Have you tried changing your algorithms declaration to...?
algorithms: {
serverHostKey: [ 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1', 'hmac-sha1-96' ],
}
Im new to Node.js and keep getting the Error: Route.get() requires callback functions but got a [object Undefined] error
and Ive checked out the following question and either dont understand or im still doing something wrong
Express routes: .get() requires callback functions but got a [object Object]
.get() requires callback functions but got a [object Undefined]
Error: Route.get() requires callback functions but got a [object Undefined]
Node Route.get() requires callback function but got a [object undefined]
my file structure is
server.js
routes/api/geolocations.js
routes/api/geolocations/regions.js
routes/api/geolocations/destination.js
ROOT: server.js
var geolocation = require('./routes/api/geolocation')(app);
app.get('/geolocation/', geolocation.delegate);
then I pass my data to routes/api/geolocations.js by using
geolocation.delegate(unparsedData);
from there I parse the data and send it down it's appropriate child routes.
PARENT: geolocations.js in my routes/api/geolocations.js
var destination = require('./geolocations/destination');
var region = require('./geolocations/region');
module.exports = function(app) {
return {
app.get('./geolocation/region', region.delegate);
app.get('./geolocation/destination', destination.delegate);
delegate: function(unparsedData, req, res) {
var data =[setup package for child states using unparsedData]
//HERE Id like to pass the new `data` to region or destination using the following
region.delegate(data);
//OR
destination.delegate(data);
CHILDREN: region.js / destination.js in routes/api/geolocations/regions.js or routes/api/geolocations/destination.js
module.exports = function(app) {
return {
delegate: function(data, req, res) {
...do stuff
}
}
}
UPDATE: I guess I dont know where to set up my routes, in server.js or if i can in geoloaction.js, does it matter, do need to do something like this in server.js?
var regions = require('./routes/api/geolocation/regions')([pass stuff here]);
geolocation.get('./routes/api/geolocation/regions', regions.delegate);
You should use express.js easy setup and run.
Simply download IntelliJ IDEA, find free version, then install. Then run the application and goto File->Setting->Plugin and search for NodeJS then install. Followed to this you need to Enable it. To do this goto File->Setting->Language & Frameworks->open arrow-> JavaScriptopen arrow->Libraries->Enable Node.js Core.
File Structure
routes/api/geolocations.js
routes/api/geolocations/regions.js
routes/api/geolocations/destination.js
You can have a look at the below code that might help you get started.
//------------------------------------------------------------------------
var express = require('express');
var router = express.Router();
var regions = require('../api/geolocations/regions');
var destination = require('../api/geolocations/destination');
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* geolocation.js */
router.get('/', function(req, res, next) {
var region_ext = regions.to_export;
var destin_ext = destination.to_export;
res.render('index', {
title: 'Geolocation',
region: region_ext,
destination:destin_ext
});
});
module.exports = router;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* region.js */
var to_export = function () {
return 'this is from regions';
}
module.exports.to_export = to_export();
//------------------------------------------------------------------------
//------------------------------------------------------------------------
/* destination.js */
var to_export = function () {
return 'this is from destination';
}
module.exports.to_export = to_export();
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//In app.js, just change
var routes = require('./routes/api/geolocations');
//------------------------------------------------------------------------
jfriend00 is right, You got a little mess there. Maybe you should consider make use of next(), since if you use it the other middlewares will have a chance of manipulating the request.
I am trying to post an array to my server. But I have difficulties in doing it properly.
The array I am trying to post, is an array of objects which is dynamically structured, thus I don't know it's length.
To be more precise, my array is of the form.
var names =[{id:1, name:"nick"},{id:2,name:"bob"},{id:3,name:"john"}.....{id:n, name:"whatever"}]
I am posting using jquery:
$.post("save_names", {
'names[]': names
}, function(results) {
alert(results);
});
My node code, is the following: (I use stormpath-express)
app.post('/save_names', config.access_group, function(req, res) {
console.log("body ", req.body);
});
This way i am getting the following from the console.log
body { 'names[]': [ '[object Object]', '[object Object]', '[object Object]' ] }
When i try to print the array : console.log("body ", req.body.names);
I get body undefined
Can somebody explain why this is happening? How to solve my error, and why can't I just post names:names and simply work?
You're sending your data incorrectly. You can examine request in Development tools. You'll see something like this:
Form Data
names[]:[object Object]
names[]:[object Object]
names[]:[object Object]
names[]:[object Object]
Try converting data to JSON yourself:
$.post("save_names", {
'names[]': JSON.stringify(names)
}, function(results) {
alert(results);
});
Don't forget to correctly access your array: console.log("body ", req.body['names[]']);.
Yes, you req.body contains key names[], not names. So you can either grab from req.body['names[]'] or rewrite code to have name object:
$.post("save_names", {
names: names
}, function(results) {
alert(results);
});
And express code:
app.post('/alter_offer_sort', config.access_group, function(req, res) {
console.log("body ", req.body.names);
});
P.S. probably you grab [] names from a GET Query. It's not how POST works.
UPDATE:
I also don't notice, that there is just string of object, so initialize bodyParser.
First install body-parser:
npm install --save body-parser
Then modify code to this:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
I have a controller accessed from a route through a
router.post('/human',human.create);
human is imported through its controller file which contains the following :
var config = require(__dirname + '/../config/config'),
logger = require(__dirname + '/../lib/logger'),
util = require(__dirname + '/../helpers/util');
exports.create = function(request, response, next){
response.send({
id: "human_103tsG2eZvKYlo2CW5yEDyUe",
firstName: "Patricia",
middleName: null,
lastName: "Cesar",
sex: "Female",
birthdate: null
});
};
Inside this create function, I can do
console.log(request);
And a humongous JSON object will apear in the terminal, including the attribute I need : body.
However, when I do, console.log(request.body), it goes undefined.
Am I missing a particular functionality of Node or Express that needs to be coded out?
I guess you are using the express 4.x which decoupled lots of middleware packages, as #shredmill metioned, you should use
bodyParser = require ('body-parser')
...
app.use(bodyParser.json()); //i found this works for me comparing to use bodyParser()
req.body is not pre-parsed for you automatically. You should explicitly use the connect.json() middleware for this:
var connect = require('connect');
router.post('/human', connect.json(), human.create);