How do I update json data in postgres sql in nodejs? - node.js

my data structure schema is like
users(
id serial primary key,
data json
);
I want to update data key.
I'm using node-postgres library and So far I have tried something like this:
pg.connect(process.env.DATABASE_URL, function(err, client, done) {
var queryString = "UPDATE users SET data =" + myNewJsonData + " WHERE id = " + userIdToEdit + ";";
client.query(queryString, function(err, result) {
done();
if (err) {
res.send("Failed to update user data ");
throw err;
} else {
res.send("Successfully updated user data!! ");
}
});
});
this is not working, I'm getting error invalid input syntax for type json
Can anyone help, Thanks.

So it was a syntax error, All I had to do stringfy json data and put that in 'quotes'
pg.connect(process.env.DATABASE_URL, function(err, client, done) {
var newJsonDataStringyfied = JSON.stringify(myNewJsonData)
var queryString = "UPDATE users SET data = '" + newJsonDataStringyfied + "' WHERE id = " + userIdToEdit + ";";
client.query(queryString, function(err, result) {
done();
if (err) {
res.send("Failed to update user data ");
throw err;
} else {
res.send("Successfully updated user data!! ");
}
});
});

Related

Trouble receiving Nodejs response from a Post request (not using express)

My server receives my post request just fine, but I get no response from the server (and nothing through my web inspector either). I've set up my headers for cross origin and everything. Here is my nodejs server code. Code in question is at the bottom.
http.createServer(function (request, response) {
if(request.url === '/action'){
//console.log("momma I made it");
let body = '';
request.on('data', chunk => {
body += chunk.toString();
});
request.on('end', () => {
var log = JSON.parse(JSON.stringify(parse(body)));
console.log(log);
if(log.accT == 'Admin') {
if(log.account == 'nUser'){
console.log("this is an new user");
randnum = random();
var sql = "INSERT INTO Admin (adminName, adminEmail, adminPassword, adminID) VALUES ('" +log.username+ "', '" +log.email+ "', '" +log.password+ "', '" +randnum+ "')"
con.query(sql, function (err, result) {
if (err) throw err;
response.end('new user created, changed response remotely')
});
}
if(log.account == 'eUser'){
console.log("this is an existing user");
var sql = "SELECT adminName,adminPassword FROM Admin WHERE adminName = '"+log.username+"'";
con.query(sql, function (err, result, fields) {
if (err) throw err;
//var pass = parse(result);
if(result.length != 0 && result[0].adminPassword === log.password) response.end('youre in big guy')
else response.end('wrong username or password');
});
}
}
if(log.accT == 'Sponsor') {
if(log.account == 'nUser'){
console.log("this is an new user");
randnum = random();
var sql = "INSERT INTO Sponsor (adminEmail,sponsorEmail, sponsorName, sponsorPassword, sponsorID) VALUES ('" +log.authEmail+ "','" +log.email+ "', '" +log.username+ "', '" +log.password+ "', '" +randnum+ "')"
con.query(sql, function (err, result) {
if (err) throw err;
response.end('new user created, changed response remotely')
});
}
if(log.account == 'eUser'){
console.log("this is an existing user");
var sql = "SELECT sponsorName,sponsorPassword FROM Sponsor WHERE sponsorName = '"+log.username+"'";
con.query(sql, function (err, result, fields) {
if (err) throw err;
//var pass = parse(result);
if(result.length != 0 && result[0].sponsorPassword === log.password) response.end('youre in big guy')
else response.end('wrong username or password');
});
}
}
if(log.accT == 'Driver') {
if(log.account == 'nUser'){
console.log("this is an new user");
randnum = random();
var sql = "INSERT INTO Driver (sponsorEmail, driverName, driverEmail, driverPassword, driverID) VALUES ('" +log.authEmail+ "','" +log.username+ "','" +log.email+ "', '" +log.password+ "', '" +randnum+ "')"
con.query(sql, function (err, result) {
if (err) throw err;
response.end('new user created, changed response remotely')
});
}
if(log.account == 'eUser'){
console.log("this is an existing user");
var sql = "SELECT driverName,driverPassword FROM Driver WHERE driverName = '"+log.username+"'";
con.query(sql, function (err, result, fields) {
if (err) throw err;
//var pass = parse(result);
if(result.length != 0 && result[0].driverPassword === log.password) response.end('youre in big guy')
else response.end('wrong username or password buckaroo');
});
}
}
if(log.action == 'update'){
//response.write('hello');
}
//response.end('ok');
});
//response.writeHead(200)
//fs.createReadStream('server2.html').pipe(response) // do NOT use fs's sync methods ANYWHERE on production (e.g readFileSync)
}
if(request.url === '/myaction'){
response.writeHead(200)
fs.createReadStream('SignUp.html').pipe(response) // do NOT use fs's sync methods ANYWHERE on production (e.g readFileSync)
}
if(request.url === '/myaction2'){
response.writeHead(200)
fs.createReadStream('SignIn.html').pipe(response) // do NOT use fs's sync methods ANYWHERE on production (e.g readFileSync)
}
if(request.url === '/?action=update'){
//response.write('hello Isaac');
}
if (request.method == 'POST') {
console.log("POST");
var body = '';
request.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
});
request.on('end', function () {
console.log("Body: " + body);
});
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
response.setHeader('Access-Control-Allow-Headers', 'Content-Type');
response.writeHead(200, {'Content-Type': 'text/html'});
response.end('post received');
}
and here is my html receiving code
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "url not posted because I have no security", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
};
xhttp.send('action=update');
And my server receives the message just fine. Any help is greatly appreciated thank you!
Nodejs http doesn't have header method. You have to use setHeader method response.setHeader('Access-Control-Allow-Origin', '*');
I had a similar problem an earlier stage, when I tried to send a response to HTML just a plain text. it's doesn't send a response to HTML. so what I did that is i have stored value in variable and given response.end(variable_name); and that was worked fine...
please correct me if am wrong.

prepared statements node-postgresql error with null result

i am new in node.js and postgresql. am allready connected with postgres db and execute some test code. after am going to use prepared statements.am create a sample login script. if user exist it return username else return message "invalid username or password". if username and password is correct,it return username. but no data will present , then could not return message. my openion is that , the control will crashed after executing cliend.end() function.
this is my code
UserLogin.get = function(userName, callBack) {
pg.connect(pgConString, function(err, client, done) {
if (err) {
callBack("DB connection failed. " + err, null);
return;
}
var selectQuery="SELECT * from " + TABLE + " WHERE userName=($1)";
var query=client.query({
text:selectQuery,
values:[userName],
name:"selectQuery"});
query.on("error", function (error) {
callBack("DB fetch failed. Error Message: " + err, null);});
query.on('row', function(row) {
callBack(null, row);});
query.on("end", function (result) {
client.end();
return;
});
});
}
if row is empty, not return to callback. if row_result is not empty, its working fine.. How...???? any idea...???
finally i got the answer. thanks for u r supports
UserLogin.get = function(userName, callBack) {
pg.connect(pgConString, function(err, client, done) {
if (err) {
callBack("DB connection failed. " + err, null);
return;
}
var selectQuery="SELECT * from " + TABLE + " WHERE userName=($1)";
var query=client.query({
text:selectQuery,
values:[loginId],
name:"selectQuery"});
query.on("error", function (error) {
callBack("DB fetch failed. Error Message: " + err, null);return;});
query.on('row', function(row,result) {
result.addRow(row);
});
query.on('end', function (result) {
callBack(null,result.rows);
client.end();
return;
});
});
}
in my old code, callback will be called everytime the query fetches 1 row from the database. am just changed the logic
Your code
query.on('row', function(row) {
callBack(null, row);
});
means that the callback will be called everytime the query fetches 1 row from the database. In the case when the query has 0 results, the callback will never be called.

Blocking behaviour in node-mysql

I'm playing with node.js and node-mysql and I'd like to understand the following:
connection.connect(function(err) { if (err) throw err; });
console.log(" beginn insert "+ Date() );
for (var i=0;i<200;i++){
connection.query('INSERT INTO animals SET ?', {name: "tiger!"});
}
connection.end();
console.log(" end insert " + Date() );
The output is always ' beginn insert ' immediately followed by ' end insert ' and then only the database starts working. How is it possible that these node-mysql statements seem to be non-blocking?
Thanks, Felix
Node itself is non-blocking for IO so queries such as these do not block. Instead you need to pass a callback function when the query completes:
var queries = 0;
connection.query("INSERT INTO animals SET ?", {name: "tiger!"},
function (err) {
// handle error?
queries++;
if (queries == 200) {
// Last query has finished running
}
});
Use Async; something like the following:
console.log(" beginning insert "+ Date() );
// create your queries as an array of objects
queries = [];
for (var i=0;i<200;i++){
queries.push({name: "tiger!"});
};
async.map(queries, myQuery, function(err, data){
// Here all of your queries are done
connection.end();
console.log(" end insert " + Date() );
});
function myQuery(name, callback){
connection.query('INSERT INTO animals SET ?', [name], function(err, result) {
if(err){
console.error(err);
callback(err, null);
}else{
callback(null, result);
}
});
}

Remove a MongoDB Document using Express JS

I have careted an application that interacts with MongoDb using NodeJS (Express JS). I am trying to remove a document using the "_id" (the one generated by MongoDB). The following piece of code just logs "Deleted Successfully", but does not actuall remove the record:
app.post('/TaskDone', function (req, res) {
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db;
var server = new Server('localhost', 27017, { auto_reconnect: true });
var database = new Db('pending-list-2', server);
database.open(function (err, db) {
if (!err) {
console.log("Connected for Deletion");
db.collection('tasks', function (err, coll) {
var str = "{_id :"+"ObjectId(" + "\"" + req.body + "\"" + ")" + "}";
console.log(str);
coll.remove(str, function (err) {
if (err) console.log(err);
else console.log("Deleted successfully");
}
);
});
}
});
});
If I use the MongoDB client and just run db.tasks.remove({_id:ObjectID("idhere")}) , it works. Is there something wrong with the express js code that I have written. I have tried a lot of things but nothing seems to work.
You must create an ObjectID from the mongodb library:
Also this is expected that you do not have any error. The remove() is executed, but the filter is probably invalid.
So you will have to write something like like:
var mongodb = require('mongodb');
...
...
collection.remove(
{_id: new mongodb.ObjectID( req.body) },
function (err, result){
//check result to see how many document are deleted
});
Try as below:
var id = {
_id: req.body.id
};
var collection = db.collection("tableName");
collection.remove(id, function(err, records){
if(err){
console.log("Error" + err);
}
else{
console.log("Omega Job Removed");
}
});

Node.js Async | insert into postgresql database results from api

I am quite newbie with node.js. What i am trying to achieve is the following:
Connect to my postgresql database and get info of a place (id, coordinates).
call a weather api and get the info of that spot using the coordinates obtained in the previous step.
Insert the returned json in the database. I get 8 hourly objects, with the weather info every 3 hours (0,3,6,9,12,15,18,21). I need to iterate through this objects and the store them in 8 records in the database.
I wrote the following code:
app.get('/getapi', function(req, res){
var json_bbdd;
//------------ BBDD CONNECTION----------------
var pg = require('pg');
var conString = "postgres://postgres:postgres2#localhost/places";
var client = new pg.Client(conString);
client.connect(function(err) {
if(err) {
console.log('could not connect to postgres');
}
client.query('SELECT * from places where id=3276', function(err, result) {
if(err) {
console.log('error running query');
}
json_bbdd=result.rows[0];
var coords = JSON.parse(json_bbdd.json).coordinates;
var id = json_bbdd.id;
var input = {
query: coords[1] + ',' + coords[0] ,
format: 'JSON',
fx: '',
callback: 'MarineWeatherCallback'
};
var url = _PremiumApiBaseURL + "marine.ashx?q=" + input.query + "&format=" + input.format + "&fx=" + input.fx + "&key=" + _PremiumApiKey + "&tide=yes";
$.ajax({
type: 'GET',
url: url,
async: false,
contentType: "application/json",
dataType: 'jsonp',
success: function (json) {
var date= json.data.weather[0].date;
for (var i=0; i < 8; i++){
var hourly = json.data.weather[0].hourly[i];
var time= hourly.time;
client.query('INSERT into parte (id, date, time) VALUES($1, $2, $3)', [id, date, time],
function(err, result) {
if (err) {
console.log(err);
} else {
console.log('row inserted: ' + id + ' ' + time);
}
});
} // FOR
},
error: function (e) {
console.log(e.message);
}
});
client.end();
});
});
});
The steps 1 and 2 are performed perfectly. The third step, on the other hand, does nothing and it doesn't even throw an error.
I read in this post: node-postgres will not insert data, but doesn't throw errors either that using async module could help but i have no idea how to rewrite the code. I need some help.
Regards,
Aitor
I didn't test your snippet, I can only help you with things which looks bad to my eyes.
It is better not to use jQuery on node server. There is excellent library called request to do remote http requests.
You should better handle database errors because in your example your code will continue after DB error.
You are calling client.end() too early and at the time when you try to insert data to the database a connection is already closed. You have to move client.end() at the end of success and error functions and wait to all callbacks are done.
I think it is also better to use connection pool instead of Client.
You can possibly use JSON type in PostgreSQL to avoid serializing/deserializing JSON data in your code.
Here is revised example(untested). I didn't replace jQuery here, some minor tweaking included.
var pg = require('pg');
var conString = "postgres://postgres:postgres2#localhost/places";
app.get('/getapi', function(req, res, next){
var json_bbdd;
//------------ BBDD CONNECTION----------------
pg.connect(conString, function(err, client, done) {
if(err) {
// example how can you handle errors
console.error('could not connect to postgres');
return next(new Error('Database error'));
}
client.query('SELECT * from places where id=3276', function(err, result) {
if(err) {
console.error('error running query');
done();
return next(new Error('Database error'));
}
json_bbdd = result.rows[0];
var coords = JSON.parse(json_bbdd.json).coordinates;
var id = json_bbdd.id;
var input = {
query: coords[1] + ',' + coords[0] ,
format: 'JSON',
fx: '',
callback: 'MarineWeatherCallback'
};
var url = _PremiumApiBaseURL + "marine.ashx?q=" +
input.query + "&format=" + input.format +
"&fx=" + input.fx + "&key=" +
_PremiumApiKey + "&tide=yes";
$.ajax({
type: 'GET',
url: url,
async: false,
contentType: "application/json",
dataType: 'jsonp',
success: function (json) {
var date = json.data.weather[0].date;
var callbacks = 0;
for (var i=0; i < 8; i++) {
var hourly = json.data.weather[0].hourly[i];
var time= hourly.time;
client.query(
'INSERT into parte (id, date, time) VALUES($1, $2, $3)',
[id, date, time],
function(err, result) {
if (err) {
console.log(err);
} else {
console.log('row inserted: ' + id + ' ' + time);
}
callbacks++;
if (callbacks === 8) {
console.log('All callbacks done!');
done(); // done(); is rough equivalent of client.end();
}
});
} // FOR
},
error: function (e) {
console.error(e.message);
done(); // done(); is rough equivalent of client.end();
return next(new Error('Http error'));
}
});
});
});
});
Ok, now cam up with another problem...i was doubting of creating a new post but i think that maybe could have relation with the previous post.
The aim is to read from the database instead of one place 3 places and do the same process than before for each one.
The code is as follows (with the changes proposed by ivoszz):
app.get('/getapi', function(req, res, next){
//------------ BBDD CONNECTION----------------
pg.connect(conString, function(err, client, done) {
if(err) {
// example how can you handle errors
console.error('could not connect to postgres',err);
return next(new Error('Database error'));
}
client.query('SELECT * from places where id>3274 and id<3278', function(err, result) {
if(err) {
console.error('error running query',err);
done();
return next(new Error('Database error'));
}
var first_callback = 0;
for (var y=0; y<result.rows.length; y++) {
var coords = JSON.parse(result.rows[y].json).coordinates;
var id = result.rows[y].id;
var input = {
query: coords[1] + ',' + coords[0] ,
format: 'JSON',
fx: ''
};
var url = _PremiumApiBaseURL + "marine.ashx?q=" + input.query + "&format=" + input.format + "&fx=" + input.fx + "&key=" + _PremiumApiKey;
request(url, function(err, resp, body) {
body = JSON.parse(body);
if (!err && resp.statusCode == 200) {
var date = body.data.weather[0].date;
var callbacks = 0;
for (var i=0; i < 8; i++) {
var hourly = body.data.weather[0].hourly[i];
client.query(
'INSERT into parte (id, date, time) VALUES($1, $2, $3)',
[id, date, hourly.time],
function(err, result) {
if (err) {
console.log(err);
} else {
console.log('row inserted: ' + id + ' iteration ' + i);
}
callbacks++;
if (callbacks === 8) {
console.log('All callbacks done!from id '+id);
//done(); // done(); is rough equivalent of client.end();
//res.send("done");
}
});
} // FOR
}
else { // if the API http request throws an error
console.error(err);
done(); // done(); is rough equivalent of client.end();
return next(new Error('Http API error'));
}
}); // REQUEST API URL
first_callback++;
if (first_callback === result.rows.length-1) {
console.log('All global callbacks done!');
done(); // done(); is rough equivalent of client.end();
res.send("done");
}}
}); // SELECT from pg
}); // CONNECT to pg
}); // app.get
I don't know why it tries to insert the id=3277 three times instead of inserting id=3275, id=3276 and then id=3277... what it does instead is: it inserts the first 8 records ok the first time (id=3277), but then it throws an error saying that the records are already inserted (primary key=id,date,time) with id 3277...
It seems that first does the 3 iterations of the first FOR and then does the 3 iteration of the second FOR but with the info of the last iteration(place). I can't understand it very well...

Resources