Inserting into MongoDB using Node js - javascript

Inserting into Mongo DB using the mongojs module fails cryptically,I have two functions,setupMongoDB and pushRequestsToMongoDB(what they do is self-explanatory).
I get a request from my web-page and parse the data to JSON.
The console looks like this:
created worker: 22987
created worker: 22989
created worker: 22990
created worker: 22991
{ type: 'line',geometry: '`tvtBat~_Wnaoi#_kc~BzlxZbrvdA{fw[`mw}#' }
object
[Error: connection closed]
The code that did produces the error looks like this:
var mongo=require('mongojs');
var collections=['testData'];
var dbURL='localhost:3000/mapData';
var db=mongo.connect(dbURL,collections);
var insert=function(obj)
{
db.testData.save(obj,function(err,obj){
if(err || !obj)
{
console.log(err);
}
else
{
console.log('Data successfully inserted with _id '+obj['_id']);
}
});
};
exports.insert=insert;
This is how I use the function:
var express=require('express');
var app=express();
var mongo=require('./mongo_try');
app.use(express.bodyParser());
app.post('/map',function(req,res){
var data=req.body;
console.log(data);
console.log(typeof data);
mongo.insert(data);
});

I'm very confused at what "conn.markers.save" intends to do. Is this a mongoose call? Mongodb node native doesn't have a "save" command. Do you mean to get the "markers" collection, and then insert the data? You won't need to stringify it.
Are you using this: https://github.com/mafintosh/mongojs ?
You shouldn't have to stringify that save command either. Change this line:
conn.markers.save(obj,function(err,data){
Or if the contents of "obj" are already a string, change it to:
conn.markers.save(JSON.parse(obj),function(err,data){

Related

Cannot get objects' values from request body while trying to POST [Node.js, MySQL]

I am working on a management system, currently creating the POST requests for the api. I need the values of the request's body to post a new city in the database. The values are used in the stored procedure as parameters. Instead of the key's values which I entered, I am getting an "undefined" value, sometimes a "[object Object]".
I am using a MySQL server, hosted in the cloud by Google's services. Backend is made with Node.js, routing with Express. None of my attempts to fix the bug worked for me.
What I've tried so far:
-Parsing each key's value .toString() and JSON.stingfify() from the body
-Converting the body to Json/string, then back to a javascript object
-Getting the response's requests's body (res.req.body)
-Getting the body's response values in an array, then pushing the next element after it has been passed as a parameter to the stored procedure
-Using the 'request' npm extension to put the values I need when calling the POST method.
-Changed the values to be stored in the URL' parameters instead of the body.
-Sent the body's values as form-data, JSON file, HTML page
Controller method in cityController.js:
exports.city_post = (req, res, next)=>{
poolDb.getConnection(function (err, connection){
if(!err) {
const sql = 'CALL createNewCity(?,?)';
var zipReq = req.params.zip;
var nameReq = req.params.name;
var reqBody = JSON.stringify(req.res.body);
connection.query(sql,[zipReq,nameReq], (err,rows)=>{
if(!err){
return res.status(201).json({Message: 'City with name: '+nameReq+' and zip code: '+zipReq+' created successfully\n', rows});
}
else{
return res.status(404).json({errorMessage: err})
}
});
}
else{
return res.status(500).json({errorMessage: "server error: "+this.err});
}
console.log("\nZip Code: "+ zipReq +"\nName: " + nameReq); //for testing
console.log("\nrequest body: " + reqBody); //for testing
});
}
City route:
const express = require('express');
const router = express.Router();
const CityController = require('../controllers/cityController.js');
router.get('/', CityController.city_getAll);
router.get('/:cityzip', CityController.city_getbyzip);
router.post('/add', CityController.city_post);
...
module.exports = router;
Expected: Posting a new field in table city, status code (201).
Actual: Status code (404), no new insertion in the DB. body, req.body.zip & req.body.name are of value "undefined".
Screenshots:
-Terminal output: https://imgur.com/a/brqKZlP
-Postman request: https://imgur.com/a/ZfFcX8Z
Express doesn't parse post body by default (for some reason). You can try popular body-parser npm package, or collect the raw body data and parse from a string yourself if you don't want to add a whole new package. Here as express app:
app.use(function(req, res, next){
var data = "";
req.on('data', function(chunk){ data += chunk})
req.on('end', function(){
req.rawBody = data;
var json = JSON.parse(req.rawBody); // assuming valid json. ideally check content-type first
next();
});
});

Save html-form data in json format in a .json file using node and express with javascript

Newbie in node and express
I am taking user input from html-form and trying to append or push it in a .json file.
I have used jsonfile npm-package but it is not coming in a array format of json
code for appending-
var express = require('express');
var app = express();
//jade --> ejs -->html
app.engine('html', require('ejs').renderFile);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
var jsonfile = require('jsonfile');
var file = './userdata.json'
//trying to write via form to json
app.post('/gettingdata', function(req, res) {
var user_id = req.body.usrid;
var token = req.body.usrphone;
var geo = req.body.usrdata;
//start writing
var obj = { name: user_id , phone: token, adress: geo }
jsonfile.writeFileSync(file, obj, {flag: 'a'});
//default
//res.send(user_id + ' ' + token + ' ' + geo);
});
html -
<body>
<form action="/gettingdata" method="post">
Name:<input type="text" name="usrid" /><br>
Phone:<input type="text" name="usrphone" /><br>
RData:<input type=="text" name="usrdata" /><br>
<input type="submit" value="Submit" >
</form>
</body>
json appearing as-
{"name":"name1","phone":"8989898989","adress":"random1"}
{"name":"name1","phone":"767656568","adress":"randomdata1"}
{"name":"name1","phone":"767656568","adress":"randomdata1"}
there are no commas appearing between objects and no square brackets. I need them to be able to make parsing possible, so that I can dynamically edit and delete data from my front-end later.
Suggest any link,method or npm package to do so.If question repeated share the link of that too
I will expand on Shil's answer with some code:
// 1. Read the existing file
fs.readFile(file, (err, data) => {
if (err && err.code === "ENOENT") {
// But the file might not yet exist. If so, just write the object and bail
return fs.writeFile(file, JSON.stringify([obj]), error => console.error);
}
else if (err) {
// Some other error
console.error(err);
}
// 2. Otherwise, get its JSON content
else {
try {
const fileData = JSON.parse(data);
// 3. Append the object you want
fileData.push(obj);
//4. Write the file back out
return fs.writeFile(file, JSON.stringify(fileData), error => console.error)
} catch(exception) {
console.error(exception);
}
}
});
This is just a quick, illustrative example: it is inefficient as the file grows as it has to read and write the entire file every single time.
Note that this will create a file which contains an array of objects, which is how you make lists of objects in JSON. So your final output will look like this:
[
{"name":"name1","phone":"8989898989","adress":"random1"},
{"name":"name1","phone":"767656568","adress":"randomdata1"},
{"name":"name1","phone":"767656568","adress":"randomdata1"}
]
Seems the library u are using can't do that thing. In both methods I find this:
var str = JSON.stringify(obj, options.replacer, spaces) + '\n'
//not sure if fs.writeFileSync returns anything, but just in case
return fs.writeFileSync(file, str, options)
where it writes into file the string you have just passed into the function, so it doesn't evaluate what it is already written into the file. So it will write one json every time you call the function. It won't continue to add elements to the existing json. You should do a custom function to do it.
You could do this:
retrive what it's already in the file
parse into json
append the json object you want to add
stringify the result and save it into the file replacing what was writing first.
edit:
sources:
writeFile /
writeFileSync

Upload data from Node.js stream to ElasticSearch database

My current Node.js code creates a stream from a very large USPTO Patent XML file (approx 100mb) and creates a patentGrant object while parsing the XML stream. The patentGrant object includes publication number, publication country, publication date and kind of patent. I am trying to create a database containing all of the patentGrant objects using ElasticSearch. I've successfully added code to connect to the local ElasticSearch DB but I am having trouble understanding the ElasticSearch-js API. I don't know how I should go about uploading the patentGrant object to the DB. From the following tutorial and a previous stackoverflow question I asked here. It seems like I should use the bulk api.
Heres my ParseXml.js code:
var CreateParsableXml = require('./CreateParsableXml.js');
var XmlParserStream = require('xml-stream');
// var Upload2ES = require('./Upload2ES.js');
var parseXml;
var es = require('elasticsearch');
var client = new es.Client({
host: 'localhost:9200'
});
// create xml parser using xml-stream node.js module
parseXml = new XmlParserStream(CreateParsableXml.concatXmlStream('ipg140107.xml'));
parseXml.on('endElement: us-patent-grant', function(patentGrantElement) {
var patentGrant;
patentGrant = {
pubNo: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['doc-number'],
pubCountry: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['country'],
kind: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['kind'],
pubDate: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['date']
};
console.log(patentGrant);
});
parseXml.on('end', function() {
console.log('all done');
});
The bulk api, as it says in the docs you linked, is used for "index" and "delete" operations.
Use create https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#api-create
parseXml.on('endElement: us-patent-grant', function(patentGrantElement) {
var patentGrant;
patentGrant = {
pubNo: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['doc-number'],
pubCountry: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['country'],
kind: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['kind'],
pubDate: patentGrantElement['us-bibliographic-data-grant']['publication-reference']['document-id']['date']
};
client.create({
index: 'myindex',
type: 'mytype',
body: patentGrant,
}, function() {}
)
console.log(patentGrant);
});
without ID, it should create one id as per https://www.elastic.co/guide/en/elasticsearch/reference/1.6/docs-index_.html#_automatic_id_generation

How do I add temporary properties on a mongoose object just for response, which is not stored in database

I would like to fill a couple of extra temporary properties with additional data and send back to the response
'use strict';
var mongoose = require('mongoose');
var express = require('express');
var app = express();
var TournamentSchema = new mongoose.Schema({
createdAt: { type: Date, default: Date.now },
deadlineAt: { type: Date }
});
var Tournament = mongoose.model('Tournament', TournamentSchema);
app.get('/', function(req, res) {
var tournament = new Tournament();
// Adding properties like this 'on-the-fly' doesnt seem to work
// How can I do this ?
tournament['friends'] = ['Friend1, Friend2'];
tournament.state = 'NOOB';
tournament.score = 5;
console.log(tournament);
res.send(tournament);
});
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});
But the properties wont get added on the Tournament object and therefor not in the response.
Found the answer here: Unable to add properties to js object
I cant add properties on a Mongoose object, I have to convert it to plain JSON-object using the .toJSON() or .toObject() methods.
EDIT: And like #Zlatko mentions, you can also finalize your queries using the .lean() method.
mongooseModel.find().lean().exec()
... which also produces native js objects.

How to use a MongoDB collection in another file

I have one server file that is server.js.
I have a MongoDB connection inside this file like this:
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
client.collection('userdetails',function(err,collection)
{
Ucollection=collection;
});
});
I have another file named server2.js. In this file I have to check if a username exists or not from Ucollection (this is collection name).
How can I give the MongoDB connection to server2.js? How can I use this collection in server2.js?
You could do something like this
in server.js:
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
global.mongoHelper = {};
global.mongoHelper.db = Db;
global.mongoHelper.bson = BSON;
global.mongoHelper.server = Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
client.collection('userdetails',function(err,collection)
{
Ucollection=collection;
});
});
in server2.js
client=new global.mongoHelper.db('database' , new global.mongoHelper.server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
client.collection('userdetails',function(err,collection)
{
Ucollection=collection;
});
});
I think much cleaner way of doing this is to seprate your database configration into seprate file. Like this
in database-config.js
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
module.exports.connectDatabase = function(callback){
client.open(function(err,pClient)
{
if(err){
console.log(err);
process.exit(1);
}
module.exports.userCollection = pClient.collection('userdetails');
callback();
});
}
in server.js
var database = require('./database-config')
database.connectDatabase(function() {
//here you can reuse collection like this
database.userCollection
}
in server2.js
var database = require('./database-config')
//here you can reuse collection like this
database.userCollection
I am assuming that server.js is your main file which actually intiate server so when you run your application it connects to database and load required collections which you can use anywhere in your application like I did this is considered as best practice to re-use collections. Let me know if there is any confusion
Well you are a bit mistaken about the whole concept of modularizing the code. For your task, you should not make a second server.js. You can make another module say, verifyUser and require it in your server.js file. You may require it (may be) after your mongodb connection.
server.js
var Db=require('mongodb').Db;
var BSON=require('mongodb').BSONPure;
var Server=require('mongodb').Server;
client=new Db('database' , new Server('127.0.0.1',27017),{safe:false});
client.open(function(err,pClient)
{
exports.Ucollection=pClient;
});
});
server2.js
var mongodb = require('mongodb');
var mainApp=require('./server');
var collectionObj=mainApp.Ucollection;
var collection = new mongodb.Collection(collectionObj, 'userdetails');
Using this collection.you can query like below
collection.insert(userInfo,{safe:true},function(err, objects) {
if(!err){
console.log('Data inserted successfully.');
}
});

Categories

Resources