POST to mongodb through URL - node.js

I am trying to post data to a mongo DB through a URL of a browser. I was able to get it working using only expressJS, but I am having difficulty getting it working with mongodb. I'm still very new to this, so I am hoping that I am just missing a simple component and that I am at least on the right track.
When I enter "http://localhost:27017/api/users?id=4&token=sdfa3" or "http://localhost:27017/nodetest5/api/users?id=4&token=sdfa3" into the url, I'd like to see "4 sdfa3" on the webpage. Right now I am just getting a webpage with the message: "It looks like you are trying to access MongoDB over HTTP on the native driver port."
Here is my server.js file:
// packages
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var app = express();
var bodyParser = require('body-parser');
//db stuff
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest5');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded
//make accessible mongo db accessible to router
app.use(function(req, res, next){
req.db = db;
next();
})
// routes
app.get('/api/users', function(req, res) {
//get values from URL
var id = req.param('id');
var token = req.param('token');
res.send(user_id + ' ' + token + ' ');
});
// POST to localhost
// parameters sent with
app.post('/api/users', function(req, res) {
//internal DB value
var db = req.db;
//values from URL
var user_id = req.body.id;
var token = req.body.token;
//set collection
var collection = db.get('usercollection');
//Submit to DB
collection.insert({
"id" : id,
"token" : token
}, function (err, doc){
if (err) {
res.send("Error encountered when trying to add entry to database.");
}
else {
res.send(user_id + ' ' + token + ' ');
}
});
});
Thank you!

The HTTP interface for MongoDB can be accessed via port number 28017. You'll need to provide the --rest option to mongod:
`$ mongod --rest`
You can read more in the HTTP Interface documentation.
You should exercise caution when using the HTTP interface. From the MongoDB documentation:
WARNING
Ensure that the HTTP status interface, the REST API, and the JSON API are all disabled in production environments to prevent potential data exposure and vulnerability to attackers.

Related

saving data to mongodb using nodejs

I am self learning nodeJS, Now I tried to insert data in MongoDB and this my goal
insert values in here and once submit button is clicked, should save the data successfully to mongodb and this should return a successful message.
But this is the error
TypeError: Cannot read property 'location' of undefined
Here are the code snippets
const express = require('express');
const dotenv = require("dotenv").config();
const address = process.argv[2];
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const app = express();
//INSERT TO MONGO DB
//connect to mongo db
mongoose.connect('mongodb://localhost/weathertest2');
mongoose.Promise = global.Promise;
//create weather schema
const WeatherSchema = new Schema({
location:{
type: String
},
temperature:{
type: String
},
observationTime:{
type: String
}
});
const Weather = mongoose.model('weather', WeatherSchema);
// post request
app.post('/new', function(req, res){
new Weather({
location : req.body.location,
temperature: req.body.temperature,
observationTime : req.body.observationTime
}).save(function(err, doc){
if(err) res.json(err);
else res.send('Successfully inserted!');
});
});
// listen for request
app.listen(process.env.port || 9000, function(){
console.log('now listening for testing request');
});
app.use(express.static('public'));
Try using the body-parser middleware alongside with express:
https://www.npmjs.com/package/body-parser
const bodyParser = require("body-parser");
/*
* Parses the text as URL encoded data (which is how browsers tend to send
* form data from regular forms set to POST) and
* exposes the resulting object (containing the keys and values) on req.body
*/
app.use(bodyParser.urlencoded({ extended: true }));
This way the data from the form should be included in the request body (req.body.location)
It seems that the body of the request is undefined. This might be because express isn't parsing the request body correctly. The solution is probably to use a body parser.
npm install --save body-parser
Then import body-parser into your file:
const bodyParser = require('body-parser')
Then place this line before the "/new" handler:
app.use(bodyParser)

NodeJS unable to get

new to NodeJS and I am trying to get a basic endpoint going. I actually have three different controllers, but one of them will not work. Here is my app.js
var express = require('express');
var app = express();
var db = require('./db');
var config = require('./config/config'); // get config file
global.__root = __dirname + '/';
var ApiController = require(__root + 'auth/ApiController');
app.use('/api/auth', ApiController);
var UserController = require(__root + 'user/UserController');
app.use('/api/users', UserController);
var AuthController = require(__root + 'auth/AuthController');
app.use('/api/auth/users', AuthController);
module.exports = app;
The UserController and AuthController work great but the ApiController:
//this controller handles api token
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());
router.get('/apiToken') , function(req, res) {
console.log("received request at /apiToken");
res.status(200).send({ token: config.api.token });
};
module.exports = router;
When I try this in Postman you can see:
I know it has to be something really simple because the failing call is nearly identical to the working ones - but I just don't see it.
You have a coding mistake here with a closing paren in the wrong place on this line that happens to not make an interpreter error, but does not execute as intended:
router.get('/apiToken') , function(req, res) {
// here ^
So change this:
router.get('/apiToken') , function(req, res) {
console.log("received request at /apiToken");
res.status(200).send({ token: config.api.token });
};
to this:
router.get('/apiToken', function(req, res) {
console.log("received request at /apiToken");
res.send({ token: config.api.token });
});
FYI, there is no need to do res.status(200) as that is the default status already. You can just use res.send(...) and the status will be set to 200 automatically. You only need to use res.status(xxx) when you want the status to be something other than 200.
Also, running your code though something like jshint will often complain about these types of mistakes that (somewhat by accident) don't throw an interpreter error.

Node.js Mongoose model not saving without error

Making this simple Node.js Express API I encountered an odd problem:
I am creating a model and inserting data into it and then saving it to my MongoDB. But the record is never saved but I also don't get any error. I have checked if MongoDB is running and both syslog for Node errors and mongod.log for MongoDB errors as well as my own Wilson debug.log file. All contain no errors.
I use postman to test the API and do get a response every time. It's just that the data does not get saved to MongoDB (I used the mongo console with db.collection.find() to check for inserted records).
Any idea why this could be happening?
my code:
api.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var http = require('http');
var https = require('https');
var fs = require('fs');
var winston = require('winston');
// Configure logging using Winston
winston.add(winston.transports.File, { filename: '/home/app/api/debug.log' });
winston.level = 'debug';
// Request body parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Enable https
var privateKey = fs.readFileSync('path to private key');
var certificate = fs.readFileSync('path to cert file');
var credentials = {
key: privateKey,
cert: certificate
};
// ROUTERS
var router = express.Router();
var speciesRouter = require('./app/routes/speciesRouter');
router.use('/species', speciesRouter);
// Routes prefix
app.use('/api/v1', router);
// SERVER STARTUP
http.createServer(app).listen(3000);
https.createServer(credentials, app).listen(3001);
speciesRouter.js
var express = require('express');
var mongoose = require('mongoose');
var router = express.Router();
var Sighting = require('../models/sighting');
var winston = require('winston');
// Database connection
var dbName = 'dbname';
mongoose.connect('mongodb://localhost:27017/' + dbName);
var db = mongoose.connection;
db.on('error', function(err){
winston.log('debug', err);
});
router.route('/')
.post(function(req, res) {
var sighting = new Sighting();
sighting.user_key = req.body.user_key;
sighting.expertise = req.body.expertise;
sighting.phone_location = req.body.phone_location;
sighting.record_time = req.body.record_time;
sighting.audio_file_location = '/var/data/tjirp1244123.wav';
sighting.probable_species = [{species_name:'Bosaap', percentage:100}];
var error = '';
winston.log('debug', 'test');
// This does not get execute I suspect..
sighting.save(function(err) {
winston.log('debug', 'save');
if (err) {
winston.log('debug', err);
error = err;
}
});
res.json({
probable_species: probable_species,
expertise: req.body.expertise,
error: error
});
});
module.exports = router;
sighting.js (model)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SightingSchema = new Schema({
user_key: String,
expertise: Number,
phone_location: { lat: Number, lng: Number },
record_time: Number,
audio_file_location: String,
probable_species: [{ species_name: String, percentage: Number }]
});
module.exports = mongoose.model('Sighting', SightingSchema);
Did you try updating your mongodb.
sudo npm update
You can try using promise.
return sighting.save().then(function(data){
console.log(data); // check if this executes
return res.json({
probable_species: probable_species,
expertise: req.body.expertise,
error: error
});
}).catch(function(err){
console.log(err);
});
One more thing dont use res.json outside the save function because in async code it will run without waiting for save function to complete its execution

how to get the values from postman extention "form-data" values

I am using node js with express framework and rest api
for rest api client i am using postman extension with chrome browser
here i am able to get values from option "x-www-form-urlencoded" but i am not able to get values from "form data" i want to get values from "form data" option and also need to upload image file.
please help me any to achieve this. i want to get values from "form data" option and also image. please help me.
Below i have mentioned code what i have used.
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var http = require('http').Server(app);
var mysql = require('mysql');
var util = require('util');
var trim = require('trim');
var validator = require('validator');
var bodyParser = require('body-parser');
var Ingest = require('ingest');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var type = upload.single('recfile');
passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
async = require('async');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/upload', function(req, res){
console.log(req.file); // "form-data" values not able to get here
console.log(req);// "form-data" values not able to get here
console.log('body : '+JSON.stringify(req.body));// "form-data" values not able to get here
});
i didn't set any content type in postman header
app.post('/upload', function(req, res){
console.log('req.headers \n '+JSON.stringify(req.headers));
console.log('req.body.file :- '+req.body.file);
console.log('\n\n req.body :- '+JSON.stringify(req.body));
});
I got the below result for the above code.
req.headers
{"host":"localhost:3001","connection":"keep-alive","content length":"5808","cache-control":"no-cache","origin":"chrome-extension://mkhojklkhkdaghjjfdnphfphiaiohkef","password":"password","user-agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36","username":"User2","content-type":"multipart/form-data; boundary=----WebKitFormBoundaryV4zAIbjEyKYxLRWe","accept":"*/*","accept-encoding":"gzip, deflate","accept-language":"en-US,en;q=0.8","cookie":"connect.sid=s%3Atz4f1ZgJkaAjuDD1sOkMB9rr.Z8EUIyxEcr0EyFQL96v0ExGRidM3SAVTx8IIr52O0OI"}
req.body.file :- undefined
req.body :- {}
Yes the same problem facing me several times and according my experience you do't set the content-type in postman header because it should be undefined and node server automatically set the content type according to requirement. If you set the content-type then you do't get any image and other data in the node server .
You get the image from the req.body.file
you get the other data from req.body
app.use(multipart()) in middleware
Procedure how to use multipart as middleware
var multipart = require('connect-multiparty');
global.app = module.exports = express();
app.use(multipart());
I got solution with help of the below code
var express = require('express');
var router = express.Router();
var util = require("util");
var fs = require("fs");
var formidable = require('formidable');
var path = require('path');
router.post("/upload", function(req, res, next){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
// `file` is the name of the <input> field of type `file`
console.log(files);
console.log(fields);
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
form.on('error', function(err) {
console.error(err);
});
form.on('progress', function(bytesReceived, bytesExpected) {
var percent_complete = (bytesReceived / bytesExpected) * 100;
console.log(percent_complete.toFixed(2));
});
form.on('end', function(fields, files) {
/* Temporary location of our uploaded file */
var temp_path = this.openedFiles[0].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[0].name;
/* Location where we want to copy the uploaded file */
var new_location = 'public/images/';
fs.readFile(temp_path, function(err, data) {
fs.writeFile(new_location + file_name, data, function(err) {
fs.unlink(temp_path, function(err) {
if (err) {
console.error(err);
} else {
console.log("success!");
}
});
});
});
});
});
I think you need to use body-parser for this and also need to update your app.js as
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
I was facing same problem I was not able to get form data fields body parser is not enough to get those values. Hitting google searched a lot of stuff about it but nothing works. Here is the solution how I got form data values.
Note: I am using typescript instead of js
Install multer package: npm i multer
Now in app.ts or app.js import accordingly:
import multer from "multer"
Define the multer function
const upload = multer(); // config
After body parser:
app.use(upload.any());

Can't get users using restful API with node and mongodb

When I set up the route for users in server.js and test with postman/localhost I get the error message, cannot GET /users. Same with any other crud operation. How can I fix this route?
server.js
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var router = express.Router();
var mongoOp = require("./models/mongo");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({"extended" : false}));
router.get("/",function(req,res){
res.json({"error" : false,"message" : "Hello World"});
});
router.route("/users")
.get(function(req,res){
var response = {};
mongoOp.find({},function(err,data){
// Mongo command to fetch all data from collection.
if(err) {
response = {"error" : true,"message" : "Error fetching data"};
} else {
response = {"error" : false,"message" : data};
}
res.json(response);
});
});
app.use('/',router);
app.listen(3000);
console.log("Listening to PORT 3000");
mongo.js
var mongoose = require("mongoose");
mongoose.connect('mongodb://localhost:27017/meanapi');
var mongoSchema = mongoose.Schema;
var userSchema = {
"userEmail" : String,
"userPassword" : String
};
module.exports = mongoose.model('userLogin', userSchema);
something helpful for these cases is to set NODE_ENV=development as an environment variable and use morgan. It prints out all the requests that hit your nodejs server with status code, method, path etc.
Here's a simple way to set it up:
if ('production' != app.get('env')) {
app.use(morgan('dev'));
}
Another thing that helps in debugging is
app.on('error', function (err) {
console.error(err); // or whatever logger you want to use
});
Ass that after all the middleware and it should print out if some requests fail to get all the way to your handlers.
Hope this helps!

Resources