node.js data fetch in json model error - json

I am new to node.js
I was just making an simple application
my data is inserting properly into the database as well as fetching also from the database
But the problem is when I am trying to access it in json model it is giving me error
var express = require('express');
/*
* body-parser is a piece of express middleware that
* reads a form's input and stores it as a javascript
* object accessible through `req.body`
*
* 'body-parser' must be installed (via `npm install --save body-parser`)
* For more info see: https://github.com/expressjs/body-parser
*/
var bodyParser = require('body-parser');
// create our app
var app = express();
// instruct the app to use the `bodyParser()` middleware for all routes
app.use(bodyParser.urlencoded({ extended: true }));
// A browser's default method is 'GET', so this
// is the route that express uses when we visit
// our site initially.
app.get('/', function(req, res){
// The form's action is '/' and its method is 'POST',
// so the `app.post('/', ...` route will receive the
// result of our form
var html = '<form action="/" method="post">' +
'Enter your name:' +
'<input type="text" name="userName" placeholder="Put your name" />' +
'<br>' +'Enter your city:'+'<input type="text" name="userCity" placeholder="Put your city" />' +
'<br>' +'Enter your state:'+'<input type="text" name="userState" placeholder="Put your state" />' +
'<br>' +'Enter your country:'+'<input type="text" name="userCountry" placeholder="Put your country" />' +
'<br>' +
'<button type="submit">Submit</button>' +
'</form>';
res.send(html);
});
// This route receives the posted form.
// As explained above, usage of 'body-parser' means
// that `req.body` will be filled in with the form elements
app.post('/', function(req, res){
var userName = req.body.userName;
var userCity = req.body.userCity;
var userState = req.body.userState;
var userCountry = req.body.userCountry;
// var document = {userName:userName,userCity:userCity,userState:userState,userCountry:userCountry};
var html = 'Hello: ' + userName + '.<br>' +'City: ' + userCity + '.<br>'+'State: ' + userState + '.<br>'+'country: ' + userCountry + '.<br>'+
'Try again.';
// res.send(html);
//res.send(JSON.stringify(doc));
//lets require/import the mongodb native drivers.
var mongodb = require('mongodb');
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
//We need to work with "MongoClient" interface in order to connect to a mongodb server.
var MongoClient = require('mongodb').MongoClient;
// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost:27017/test';
// Use connect method to connect to the Server
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established to', url);
/* var userName = req.body.userName;
var userCity = req.body.userCity;
var userState = req.body.userState;
var userCountry = req.body.userCountry;
var document = {userName:userName, userCity:userCity,userState:userState,userCountry:userCountry};*/
// do some work here with the database.
var insertDocument = function(db, callback) {
db.collection('test').insertOne( {
"userName" :userName,
"userCity" : userCity,
"userState" : userState,
"userCountry" :userCountry ,
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the test collection.");
callback(result);
});
};
var findDocument = function(db, callback) {
var cursor =db.collection('test').find( );
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
console.log(doc);
// res.contentType('application/json');
res.send(JSON.stringify(doc));
/* app.get('/test', function(req, res, next) {
res.json(doc);
});*/
} else {
callback();
}
// res.send(JSON.stringify(doc));
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
findDocument(db, function() {
db.close();
});
});
});
/* var document = {name:"David", title:"About MongoDB"};
db.collection('test').insertOne(document, function(err, records) {
if (err) throw err;
console.log("Record added as "+records[0]._id);
});*/
//Close connection
// db.close();
}
});
});
app.listen(3000);
Please help me to get rid off the problem.
Thank you..
The error I am getting is cann't set headers after they are send

This kind of error usually means that you try using res.send(...) multiple times from the same route.
Here you can see that in your find document, you use a cursor.each, and send your result inside this cursor.each. This means that you send multiple results from the same route.
What you should do instead is having a variable that you use to store your result before sending it once everything is retrieved.

Related

nodejs server app.post issue XML Parsing Error: syntax error Location: http://localhost:3000/get_messages Line Number 1, Column 1:

I followed a tutorial on YouTube to create a private user to user chat.
https://www.youtube.com/watch?v=Ozrm_xftcjQ
Everything on the chat works accept that i keep getting this Error:
XML Parsing Error: syntax error Location: http://localhost:3000/get_messages Line Number 1, Column 1:
using firefox developer edition and chrome. if i click the stack trace link i get the following xml error:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /get_messages</pre>
</body>
</html>
but i have no GET calls at all..
The code looks as follows:
server.js file
var port = process.env.PORT || 3000;
//creating express instance
var express = require("express");
var app = express();
//creating http instance
var http = require("http").createServer(app);
//app.use(express.static(__dirname));
//creating socket instance
var io = require("socket.io")(http);
//create body parser instance
var bodyParser = require("body-parser");
app.use(bodyParser.json());
//enable url encode for POST requests
app.use(bodyParser.urlencoded({ extended : true }));
//create instance of mysql
var mysql = require('mysql');
//create mysql connection
// connectionLimit: 100,debug: true
var connection = mysql.createConnection({
host: 'localhost',
user: 'xxx',
password: 'xxx',
database: 'chatio'
});
connection.connect(function(error){
if(error){
console.log(error);
return;
}
console.log('database connected');
})
//enable header request for post requests
app.use(function(request, result, next){
result.setHeader("Access-Control-Allow-Origin", "*");
next();
})
//create api to return all messages
app.post("/get_messages", function(request, result){
console.log(request);
console.log(result);
connection.query("SELECT * FROM chat_messages WHERE (`from_id` = '"+request.body.sender+"' AND `to_id` = '"+request.body.receiver+"') OR (`from_id` = '"+request.body.receiver+"' AND `to_id` = '"+request.body.sender+"')", function(error, messages){
if(error){
console.log(error);
return;
}
console.log(messages);
//response will be in JSON
result.end(JSON.stringify(messages));
});
})
io.on("connection", function(socket){
socket.on("send_message", function(data){
//send event to receiver
var socketId = users[data.receiver];
io.to(socketId).emit("new_message", data);
//save in database
connection.query("INSERT INTO chat_messages (`from_id`,`to_id`,`message`) VALUES ('"+data.sender+"', '"+data.receiver+"', '"+data.message+"')", function(error, result){
if(error){
console.log(error);
return;
}
console.log('message saved');
});
})
})
http.listen(port, function(){
console.log("server started");
})
inde.php file code as follows:
//creating io connection
var io = io("http://localhost:3000");
var receiver = "johnny";
var sender = "steven";
function onUserSelected(){
$.ajax({
url: "http://localhost:3000/get_messages",
method:"POST",
cache: false,
data: {
"sender" : sender,
"receiver" : receiver
},
dataType: "json",
success: function(response){
var messages = response; //JSON.parse();
var html = "";
for(var i = 0; i < messages.length; i++){
html += "<li>" +messages[i].from_id + " says: " + messages[i].message + "</li>";
document.getElementById('messages').innerHTML += html;
}
}
});
return;
}
}
i figured it out..
the problem comes from this line:
result.end(JSON.stringify(messages));
I dont exactly understand why, but i changed it to
result.send(JSON.stringify(messages));
and now the bug is gone

NodeJS reload page but don't send user data again [duplicate]

This question already has answers here:
How to prevent form resubmission when page is refreshed (F5 / CTRL+R)
(21 answers)
Closed 4 years ago.
I have a Node Js local server and several identical html pages. On every page I save some user data input fields saved simply on a text file. My problem is that if the users refresh the page the data from the previous html page is send again and again saved on the text file. Is there a way to prevent this?
var fs = require('fs');
const log=require('simple-node-logger').createSimpleLogger();
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var port = process.env.PORT || 8000;
app.use(express.static(__dirname + '/server'));
app.use(express.static(__dirname + "/public"));
app.use('/images', express.static(__dirname +'/images'));
app.listen(port, function(){
console.log('server is running on ' + port);
});
app.get('/', function(req, res){
res.sendfile('intro.html');
});
app.post('/userID', function(req, res){
//save the userID on a text file
var userID= req.body.userID + ';';
var data = fs.appendFileSync('temporary/userID.txt', userID, 'utf8');
return res.sendfile('main.html');
});
app.post('/submit', function(req, res){
res.sendfile('main2.html');
});
Furthermore, I have also a refresh button that does the same as the browser refresh button. I s there a way to avoid the same problem?
<button>Reset</button>
and its JavaScript:
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('button').addEventListener('click', clickHandler);
});
function clickHandler(element) {
location.reload();
}
Thank you in advance!
You can use fs.readFile and check if that file contain that userId
If that is not present then append or else dont append
fs.readFile('temporary/userID.txt', function (err, fileData) {
if (err) throw err;
if(fileData.indexOf(userID) == -1){
var data = fs.appendFileSync('temporary/userID.txt', userID, 'utf8');
}
});
So, the code will be:
app.post('/userID', function(req, res){
//save the userID on a text file
var userID= req.body.userID + ';';
fs.readFile('temporary/userID.txt', function (err, fileData) {
if (err) throw err;
if(fileData.indexOf(userID) == -1){
var data = fs.appendFileSync('temporary/userID.txt', userID, 'utf8');
}
});
return res.sendfile('main.html');
});

Jawbone API Paginated Results with 'page_token'

The Jawbone API returns paginated results of 10 json objects per result set. How does one obtain the rest of the paginated results?
The API documentation for the sleeps method indicates the existence of a page_token argument in the next object of the result set. My output below is missing this. Furthermore,the FAQ indicates this page_token takes an INT (presumably epoch) timestamp.
2nd: "page_token" parameter: if the request contains the "page_token" parameter, the API will return all the workouts, in
reverse order, (capped by "limit" or default of 10) that were
completed before that page_token. The page_token is a timestamp, and
there's a special case, when the request comes with page_token=0 which
is interpreted as passing page_token = CURRENT_TIMESTAMP, ie, give all
the workouts (with a limit)
I am able to authenticate with the API and return a set of 10 results (first paginated page)... but no page_token.
...snip json...
"links": {
"next": "/nudge/api/v.1.0/users/jMdCUPXZ-InYXo1kcdOkvA/sleeps?start_time=1424699101&updated_after=0&limit=10&end_time=1438723789"
},
"size": 10
Have I misunderstood the documentation? Could it be the documentation is out of date (wrong)? Or more likely, I'm completely misunderstanding this and writing horrible JS for my node.js ...
Can someone set me straight and show me how I can retrieve ALL results, not just the first page?
var express = require('express');
var app = express();
var port = process.env.PORT || 5000;
var passport = require('passport');
var config = require('./config.json');
var ejs = require('ejs');
var https = require('https');
var fs = require('fs');
var bodyParser = require('body-parser');
var jbStrategy = require('passport-oauth').OAuth2Strategy;
var jsonfile = require('jsonfile');
var util = require('util');
var path = require('path');
/* Calculate date range */
var $today = new Date()
var $start = new Date($today); $start.setDate($today.getDate() - 180);
var $end = new Date($today);
var $startDate = Math.floor(($start).getTime()/1000);
var $endDate = Math.floor(($end).getTime()/1000);
app.use(express.logger('dev')); // log every request to the console
app.use(bodyParser.json()); // read cookies (needed for auth)
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(passport.initialize());
/* Default Authentication Path */
app.get('/',
passport.authorize('jawbone', {
scope : config.jawboneAuth.scope,
failureRedirect: '/'
})
);
/* oauth callback from jawbone */
app.get('/done', passport.authorize('jawbone', {
scope : config.jawboneAuth.scope,
failureRedirect: '/'
}), function(req, res) {
var result = JSON.parse(body); console.log(result);
res.redirect('/sleeps');
}
);
app.get('/sleeps', function(req, res) {
var options = {
access_token : config.jawboneAuth.accessToken,
refresh_token : config.jawboneAuth.refreshToken,
client_id : config.jawboneAuth.clientID,
client_secret : config.jawboneAuth.clientSecret
};
if (!config.jawboneAuth.accessToken) {
// if there's no accessToken, go get one
res.redirect('/');
} else {
var up = require('jawbone-up')(options);
var page_token = [];
do {
up.sleeps.get({
page_token : page_token,
start_time : $startDate,
end_time : $endDate
}, function(err, body) {
if (err) {
console.log('Error receiving Jawbone UP data');
res.send(err);
} else {
try {
var result = JSON.parse(body);
var next_page_path = result.data.links.next;
//var next_page_token = next_page_path.split(path.sep);
//var page_token = next_page_token[5];
//page_token = result.data.links.next
console.log(result.data);
res.json(result);
} // end try
catch(err) {
console.log(err);
res.render('userdata', {
requestTime: 0,
jawboneData: 'Unknown result'
});
} // end catch(err)
} // end else
} //end callback fun
); // end up.sleeps.get()
} // end do
while(page_token[0] > 1);
} // end if
}); // end sleeps route
// Setup the passport jawbone authorization strategy
passport.use('jawbone', new jbStrategy({
clientID : config.jawboneAuth.clientID,
clientSecret : config.jawboneAuth.clientSecret,
authorizationURL: config.jawboneAuth.authorizationURL,
tokenURL : config.jawboneAuth.tokenURL,
callbackURL : config.jawboneAuth.callbackURL,
scope : config.jawboneAuth.scope,
passReqToCallback : true
}, function(req, accessToken, refreshToken, profile, done) {
// establish a pseudo user session.
var user = {};
// If there's no preexisting accessToken,
// write one to the config file.
if (!config.jawboneAuth.accessToken){
config.jawboneAuth.accessToken = accessToken;
config.jawboneAuth.refreshToken = refreshToken;
jsonfile.writeFile('./config.json', config, {spaces: 2}, function(err) {
console.error(err);
})
}
done(null, user);
}));
// HTTPS
var sslOptions = {
key : fs.readFileSync('./.server.key'),
cert : fs.readFileSync('./.server.crt')
};
var secureServer = https.createServer(sslOptions, app).listen(port, function(){
console.log('Listening on ' + port);
});
Turns out there is an undocumented limit parameter that has replaced the page_token.
The Jawbone Developer documentation is currently out of date. As is their FAQ (API section Question# 12).
A GET request like this seems to do the trick
https://jawbone.com/nudge/api/v.1.1/users/#me/sleeps?start_time=1388603458&end_time=1420139458&limit=1000

Connect existing MySql table with Strongloop

I am trying to create an REST API which should connect to an existing table in mysql database and return the data with respective to the parameter we send.
Actually nodejs and strongloop is new to me, this is first time am working with them. I have followed their docs and created a table in mysql my running a file like below
I have followed the commands to create model, properties etc from the below github docs
https://github.com/strongloop/loopback-example-database
create-test-data.js
var server = require('./server');
var dataSource = server.dataSources.accountDB;
var Account = server.models.account;
var accounts = [
{ email: 'foo#bar.com',
created: new Date(),
modified: new Date()
}, {
email: 'bar#bar.com',
created: new Date(),
modified: new Date()
} ];
var count = accounts.length;
dataSource.automigrate('account', function(er) {
if (er) throw er;
accounts.forEach(function(account) {
Account.create(account, function(er, result) {
if (er) return;
console.log('Record created:', result);
count--;
if(count === 0) {
console.log('done');
dataSource.disconnect();
}
});
});
});
This automatically creating table and records in my database, I don't want this.
Actually I already have a different table, which I want to connect with strongloop.
I am completely clueless, any help would be appreciated.
I found this trying to do the same thing. I fixed it so it would end gracefully. Works great for me.
Original: https://gist.github.com/serkanserttop/64fc2d4465fb154066db#file-discover-js
var path = require('path');
var app = require(path.resolve(__dirname, '../server'));
var fs = require('fs');
var loopback = require('loopback');
var app_dir = './';
require('node-babel')();
var dataSource = app.dataSources.accountDs;
var db = 'myDB',
owner = 'root';
function capitaliseFirstLetter(string) {
return string.charAt(0)
.toUpperCase() + string.slice(1);
}
function jsFileString(model_name) {
return '' + 'module.exports = function(' + capitaliseFirstLetter(model_name) + ') {\n' + '\t\n' + '};';
}
function autoGenerateModelFiles() {
dataSource.discoverModelDefinitions({
schema: db
}, function(err, models) {
var count = models.length;
console.log(models.length);
models.forEach(function(model) {
dataSource.discoverSchema(model.name, {
associations: true
}, function(err, schema) {
if (schema.options.mysql.schema !== db) {
console.log('options.mysql.schema !== db', schema);
}
fs.writeFile(app_dir + 'common/models/' + model.name + '.json', JSON.stringify(
schema, null, ' '), function(err) {
if (err) throw err;
console.log('Saved ' + model.name);
});
fs.writeFile(app_dir + 'common/models/' + model.name + '.js', jsFileString(
model.name), function(err) {
if (err) throw err;
console.log('Created ' + model.name + '.json file');
});
count = count - 1;
if (len === 0) {
console.log("DONE!", count);
dataSource.disconnect();
return;
}
});
});
});
}
What you actually need is to discover model from database. There is a documentation available on a strongloop page.
http://docs.strongloop.com/display/public/LB/Discovering+models+from+relational+databases;jsessionid=1FC0E473B7F589F4F1EFC0F25D269E3E
http://docs.strongloop.com/display/public/LB/Database+discovery+API
Here is a working example:
var ds = app.dataSources.accountDB;
ds.discoverModelDefinitions(function (err, models) {
models.forEach(function (model) {
ds.discoverSchema( model.name, function (err, schema){
console.log(schema);
});
});
});
Put this code somewhere inside server.js (i.e. inside boot method). I assume that you have setup datasource correctly and also have loppback mysql connector installed.This will loop through all tables and "schema" will contain model definition discovered from database.
You can use slc arc to generate the models based on your MySQL tables, after that you should be able to use the API to perform the basic CRUD operations. In the following link you can find more information about it:
https://strongloop.com/node-js/arc/

nodejs puts post data into new json

When I sending post request by this code:
var data = '{data: 1111}'; // = JSON.stringify(message);
console.log('NotifySplitter: ' + data);
var options = cfg.splitterOptions;
options.headers['Content-Length'] = Buffer.byteLength(data)
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
});
req.write(data);
req.end();
... and getting data by this code:
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.post('/', function(request, response){
var query = request.body;
console.log(request.body);
response.end();
});
request.body contains:
{'{data: 1111}': ''}
instead expected {data: 1111}. Is it normal? How to get normal data without replacing external {} in origin data before post?
You have to set up an appropriate content-type. If you're sending json, add options.headers['Content-Type'] = 'application/json' to your request.
Also, {data: 1111} is not a JSON, it's JSON5. While it's better all around, it's not supported by default express.bodyParser(), so watch out for that.