I have problems with the REST API.
I have a file named route. In which I make a request that is then passed to the server where it is called. In my third request, I want to select an ID to pass it as an API and write to call the page inside/:id, but I only get an error (This is a POST request)
const post_inside = (req, res) => {
var config = {
user:'postgres',
database:'my',
password: '1',
host:'localhost',
port:5432,
max:10,
idleTimeoutMillis: 30000
}
var pool = new pg.Pool(config)
pool.connect(function(err, client, done){
if(err){
return console.error('error')
}
client.query("SELECT *,to_char(data_roz::date , 'YYYY-MM-DD') as data_roz from sch.idv_p where phone=$1",[req.body.login], function(err, result){
done()
return_data.pupil2 =result
if (err) {
res.end()
return console.error("error")
}
client.query('select * from table1 ($1,$2)',[req.body.login,req.body.date], function(err, result){
return_data.discipline =result
if (err){
res.end()
return console.error("error")
}
//3 HERE
client.query("select id from table3 where phone=$1",[req.body.login], function(err, result){
return_data.id =result
if (err){
res.end()
return console.error("error")
}
res.render('inside/:id',{pupil2:return_data.pupil2,discipline:return_data.discipline,id:return_data.id})
})})}}
module.exports = {
post_inside
}
server:
app.post('/inside/:id',urlencodedParser,db.post_inside)
I want to call the same file, but for example as inside/2555
Related
I am a node.js and MySQL beginner and I just started setting up and trying out some basic code.
I find these two APIs to practice, one is the API for the CRUD database, and the other is the API for judging user login / registration.I tried to merge the APIs of these two files, and the result was a problem. I think the current problem is the configuration file (conf.js).I plan to write a function and then wrap any file and use it again, so that the configuration files may not conflict, but I don’t know how to start.
These are the two API teaching URLs I practiced
http://www.expertphp.in/article/user-login-and-registration-using-nodejs-and-mysql-with-example
https://www.footmark.info/programming-language/nodejs/nodejs-restful-webapi-mysql/
index.js
var express = require("express");
var bodyParser = require("body-parser");
var app = express();
var authenticateController = require("./controllers/authenticate-controller");
var registerController = require("./controllers/register-controller");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.post("/api/register", registerController.register);
app.post("/api/authenticate", authenticateController.authenticate);
app.listen(3000);
app.js
var bodyparser = require("body-parser");
var express = require("express");
var conf = require("./conf");
var functions = require("./functions");
var user = require("./routes/user");
var app = express();
req.body
app.use(bodyparser.urlencoded({ extended: false }));
app.use(bodyparser.json());
//app.use(functions.passwdCrypto);
app.use("/user", user);
app.listen(conf.port, function() {
console.log("app listening on port " + conf.port + "!");
});
authenticate-controller.js
var connection = require('./../conf');
module.exports.authenticate=function(req,res){
var email=req.body.email;
var password=req.body.password;
connection.query('SELECT * FROM user WHERE email = ?',[email], function (error, results, fields) {
if (error) {
res.json({
status:false,
message:'there are some error with query'
})
}else{
if(results.length >0){
if(password==results[0].password){
res.json({
status:true,
message:'successfully authenticated'
})
}else{
res.json({
status:false,
message:"Email and password does not match"
});
}
}
else{
res.json({
status:false,
message:"Email does not exits"
});
}
}
});
}
register-controller.js
var connection = require('../conf');
module.exports.register=function(req,res){
var today = new Date();
var user={
"name":req.body.name,
"email":req.body.email,
"password":req.body.password,
"created_at":today,
"updated_at":today
}
connection.query('INSERT INTO user SET ?',user, function (error, results, fields) {
if (error) {
res.json({
status:false,
message:'there are some error with query'
})
}else{
res.json({
status:true,
data:results,
message:'user registered sucessfully'
})
}
});
}
user.js(models)
var mysql = require("mysql");
var conf = require("../conf");
var connection = mysql.createConnection(conf.db);
var sql = "";
module.exports = {
items: function(req, callback) {
sql = "SELECT * FROM user";
return connection.query(sql, callback);
},
item: function(req, callback) {
sql = mysql.format("SELECT * FROM user WHERE userId = ?", [req.params.id]);
return connection.query(sql, callback);
},
add: function(req, callback) {
sql = mysql.format("INSERT INTO user SET ?", req.body);
return connection.query(sql, callback);
},
delete: function(req, callback) {
sql = mysql.format("DELETE FROM user WHERE userId = ?", [req.params.id]);
return connection.query(sql, callback);
},
put: function(req, callback) {
connection.beginTransaction(function(err) {
if (err) throw err;
sql = mysql.format("DELETE FROM user WHERE userId = ?", [req.params.id]);
connection.query(sql, function(err, results, fields) {
if (results.affectedRows) {
req.body.id = req.params.id;
sql = mysql.format("INSERT INTO user SET ?", req.body);
connection.query(sql, function(err, results, fields) {
if (err) {
connection.rollback(function() {
callback(err, 400);
});
} else {
connection.commit(function(err) {
if (err) callback(err, 400);
callback(err, 200);
});
}
});
} else {
callback(err, 410);
}
});
});
},
patch: function(req, callback) {
sql = mysql.format("UPDATE user SET ? WHERE userId = ?", [req.body, req.params.id]);
return connection.query(sql, callback);
}
};
user.js(routes)
var express = require("express");
var user = require("../models/user");
var router = express.Router();
router
.route("/")
.get(function(req, res) {
user.items(req, function(err, results, fields) {
if (err) {
res.sendStatus(500);
return console.error(err);
}
if (!results.length) {
res.sendStatus(404);
return;
}
res.json(results);
});
})
.post(function(req, res) {
user.add(req, function(err, results, fields) {
if (err) {
res.sendStatus(500);
return console.error(err);
}
res.status(201).json(results.insertId);
});
});
router
.route("/:id")
.get(function(req, res) {
user.item(req, function(err, results, fields) {
if (err) {
res.sendStatus(500);
return console.error(err);
}
if (!results.length) {
res.sendStatus(404);
return;
}
res.json(results);
});
})
.delete(function(req, res) {
user.delete(req, function(err, results, fields) {
if (err) {
res.sendStatus(500);
return console.error(err);
}
if (!results.affectedRows) {
res.sendStatus(410);
return;
}
res.sendStatus(204);
});
})
.put(function(req, res) {
user.put(req, function(err, results) {
if (err) {
res.sendStatus(500);
return console.error(err);
}
if (results === 410) {
res.sendStatus(410);
return;
}
user.item(req, function(err, results, fields) {
res.json(results);
});
});
})
.patch(function(req, res) {
user.patch(req, function(err, results, fields) {
if (err) {
res.sendStatus(500);
return console.error(err);
}
if (!results.affectedRows) {
res.sendStatus(410);
return;
}
req.body.id = req.params.id;
res.json([req.body]);
});
});
module.exports = router;
conf.js
var mysql = require("mysql");
var connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "1234",
database: "farmbot",
});
connection.connect(function(err) {
if (!err) {
console.log("Database is connected");
} else {
console.log("Error while connecting with database");
}
});
module.exports = connection;
/*If I comment out the code below, I can execute the login / register API*/
/*Without commenting out, can only perform CRUD on the database*/
module.exports = {
db: {
host: "localhost",
user: "root",
password: "1234",
database: "farmbot"
},
port: 3000
};
You will have to refactor them properly. You will need only once file to begin with. Why using it twice?
Refactor them in one file instead of listening to them on different ports. Once done, you can show the code to us so that we can fix it further if there's an issue.
Start from index.js and merge app.js with it but a bit carefully. I think doing it by yourself you will learn much from it.
I wanna take the whole list of notifies from mongo db but it returns empty([]) array also I know that i need callback or shorter way of it . Do you have any idea for collecting any data from mongodb by node.js? If I call this /Notifies method (http://127.0.0.1:5000/Notifies)
var MongoClient = require('mongodb').MongoClient;
var express = require("express");
var app = express();
format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
});
app.get('/Notifies', function (req, res) {
// BAD! Creates a new connection pool for every request
console.log('connected');
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) throw err;
var coll = db.collection('Notifies');
var arr = [];
coll.find({}, function (err, docs) {
docs.each(function (err, doc) {
if (doc) {
console.log(doc);
arr.push(doc);
} else {
res.end();
}
});
});
return res.json(arr);
});
});
var port = Number(process.env.PORT || 5000);
app.listen(port, function () {
console.log("Listening on " + port);
})
Don't use for docs.each instead of this use .toArray so it will return directly a array and then use Json.stringify to convert it into json string array
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) throw err;
var coll = db.collection('Notifies');
coll.find({}).toArray(function (err, result) {
if (err) {
res.send(err);
} else {
res.send(JSON.stringify(result));
}
})
});
The problem is you are returning the empty array from within the function, before the actual DB operation occurs. You need to move the line return res.json(arr);
into the find function:
app.get('/Notifies', function (req, res) {
// BAD! Creates a new connection pool for every request
console.log('connected');
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) throw err;
var coll = db.collection('Notifies');
var arr = [];
coll.find({}, function (err, docs) {
console.log(docs);
docs.each(function (err, doc) {
if (doc) {
console.log(doc);
arr.push(doc);
} else {
res.end();
}
});
return res.json(arr);
});
});
});
Also, for future use, do not reuse variable names in nested functions (you have 3 functions that use the variable err).
I'm developing a simple rest API in Node.js, and it works middling.
This is my controller code:
...
exports.listById = function(id, callback) {
Course.findById(id, function(err, courses){
if(err){
callback({error: 'Not Found'});
}
else{
callback(courses);
}
});
}
And this is my route:
app.get('/courses/:id', function(req, res){
var id = req.params.id;
courseController.listById(id, function(resp){
res.status(200).json(resp);
});
});
This code works and show results of my collection in mongodb.
But the code below, doesn't show results with postman:
app.get('/courses/:id', function(req, res){
var id = req.params.id;
courseController.listById(id, function(err, resp){
if(err){
res.status(404).send(err);
}
else{
res.status(200).json(resp);
}
});
});
exports.listById = function(id, callback) {
Course.findById(id, function(err, courses){
if(err)
return callback(new Error('Not Found')); // You must return Error by standard
callback(null, courses); // You must set first argument (error) to null
});
}
...
// You can check that id is number
app.get('/courses/:id(\\d+)', function(req, res, next) {
var id = req.params.id;
courseController.listById(id, function(err, resp) {
if(err)
return next(err); // Pass error to error-handler (see link below)
res.status(200).json(resp);
});
Best practice for callback function is first argument as error and second as result.You should
exports.listById = function (id, callback) {
Course.findById(id, function (err, courses) {
if (err) {
callback(error);
}
else {
callback(null, courses);
}
});
}
while your route should look like this:
app.get('/courses/:id', function (req, res) {
var id = req.params.id;
courseController.listById(id, function (error, courses) {
if (error) return res.status(500) // internal server error
// if I remember correctly, sources is empty array if course not found
res.status(200).json(resp);
});
});
I am using Express.js for my app and mongodb for database (also mongodb Nativ driver).
I created a model with two functions, for getting posts and comments:
// Get single Post
exports.posts = function(id,callback){
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log('Connection established to', url);
var collection = db.collection('posts');
collection.find({psotId:id}).limit(1).toArray(function (err, result) {
if (err) {
return callback(new Error("An error has occured"));
} else {
callback(null,result);
}
db.close();
});
}
});
}
// Get post comments
exports.comments = function(id,callback){
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log('Connection established to', url);
var collection = db.collection('comments');
collection.find({postId:id}).toArray(function (err, result) {
if (err) {
return callback(new Error("An error has occured"));
}
else {
callback(null,result);
}
db.close();
});
}
});
}
and I created a route to show single post:
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,post){
if(err){
console.log(err)
}else{
post.comments(post[0].id,function(err,comments){
if(err){
console.log(err)
}
else{
res.render('blogPost',{post:post,comments:comments})
}
})
}
})
})
When I run this code I get this error:
TypeError: Object [object Object] has no method 'comments'
When I use this two function separately its work fine:
I mean like this :
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,post){
if(err){
console.log(err)
}else{
res.render('blogPost',{post:post})
}
})
})
//Get post comments
router.get('/post/1',function(req,res, next){
post.comments(1,function(err,comments){
if(err){
console.log(err)
}else{
res.render('blogPost',{comments:comments})
}
})
})
But when I use post.comments as callback for post.posts I get an error.
I wants know why this happening? After some research I couldn't find a solution and I an getting confused.
In your source code you have the following:
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,post){
if(err){
console.log(err)
}else{
post.comments(post[0].id,function(err,comments){
if(err){
console.log(err)
}
else{
res.render('blogPost',{post:post,comments:comments})
}
})
}
})
})
when you are calling post.posts you have a callback and there you have a return value which you called post (which it is the same variable name of var post = require('../models/post');
Basically change it in the callback like this:
var post = require('../models/post');
//Get single post
router.get('/post/:postId',function(req,res, next){
var id = parseInt(req.params.postId);
post.posts(id,function(err,posts){ //HERE changed post into posts
if(err){
console.log(err)
}else{
post.comments(posts[0].id,function(err,comments){
if(err){
console.log(err)
}
else{
res.render('blogPost',{post:posts,comments:comments})
}
})
}
})
})
EDIT: for better understanding I would change var post = require('../models/post'); into var postModel = require('../models/post'); SO it is much more understandable
EDIT 2: since he posted the real version code
Basically you have the same problem, line 37 of route.js is overriding the movie variable.
You have to call the variable that comes back form the callback with another name, for example movieslike you used to do in the other 2 above.
router.get('/m/:movieId',function(req,res, next){
var id = parseInt(req.params.movieId);
movie.get(id,function(err,movies){
if(err){
console.log(err)
}else{
movie.subtitles(movies[0].imdb,function(err,subs){
if(err){
console.log(err)
}
else{
res.render('moviePage',{movie:movies,subtitles:subs})
}
})
}
})
})
If you copy-pasted this from your source then its because you mispelled the method.
post.commencts
should be
post.comments
I'm having problems with saving a document in MongoDB in my Nodejitsu/MongoHQ app. Locally all works fine, but the MongoHQ db requires authentification and it fails with working user/pass (connecting to MongoDB shell with the same credentials works fine). Here is the function:
var update_user = function(user, callback) {
var client = new Db(db, new Server(host, port, {}));
var update = function (err, collection) {
collection.findOne({uid:user.id}, function(err, doc) {
if (err) { throw err; }
if (!doc) doc = { uid: user.id }
doc.img = user.img;
doc.name = user.name;
collection.save(doc, {safe: true}, function(err, doc) {
if (err) { throw err; }
callback(user);
});
});
};
client.open(function(err, client) {
if (err) { throw err; }
client.authenticate(user, pass, function(err, result) {
client.collection('users', update);
});
});
}
What I'm doing wrong here?
UPD: err parameter of authenticate method has the following value:
{ [MongoError: auth fails] name: 'MongoError', errmsg: 'auth fails', ok: 0 }
I checked the stored password & username again, they work for logging in the MongoHQ shell.
If your credentials are for an admin user account you must target the admin database in your authenticate call:
client.authenticate(user, pass, {authdb: 'admin'}, function(err, result) {
client.collection('users', update);
});