I was recently using a function to upload files to a mongodb database successfully. However after moving those functions into a file (to clean up) and exporting that file then requiring it in my route, the database now creates documents with only null values like so:
_id:ObjectId("xxxxxxxxxxxxxxx")
name:null,
value:null,
image:null,
desc:null
I don't know what might be causing this, I am logging the argument object that i'm trying to insert from inside the function 'insertProducts' and the item.name is not null. Sorry I'm new to mongodb :/
maybe someone can point me in the right direction?
CRUD.js
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
const removeProducts = function(req,res){
MongoClient.connect('mongodb://localhost', (err, client) => {
if (err) {
throw err;
}
let db = client.db('account-app');
let products = db.collection('products');
let users = db.collection('users');
try{
products.remove({ _id: req.body.id }, function(err) {
if (!err) {
console.log('removed item')
}
});
}
catch(err){
console.log('Error while inserting', err)
}
client.close()
res.redirect('/addItems')
})
}
const insertProducts = function(item,res){
console.log("item name",item.name)
MongoClient.connect('mongodb://localhost', (err, client) => {
if (err) {
throw err;
}
let db = client.db('account-app');
let products = db.collection('products');
try{
products.insertOne(item)
console.log('item inserted')
}
catch(err){
console.log('Error while inserting', err)
}
client.close()
res.redirect('/admin/addItems')
})
}
module.exports={removeProducts: removeProducts, insertProducts: insertProducts}
my admin route that requires the crud functions
const crudOps = require('../utils/admin/CRUD') //require CRUD functions
// Adding new items
// --------------------------------------------------
router.post('/addNewItems', (req, res, next) => {
console.log(req.body.name)
let item = {
name:req.body.name,
file: binary(req.files.image.data),
value: req.body.value,
desc: req.body.desc
}
crudOps.insertProducts(item, res)
});
That connection URL looks wrong. Generally, it has the format:
mongodb://localhost:27017/mydatabase
Try replacing the connection string with the appropriate one for your database and see if that works. Also, the docs normally have insertOne statements like this so maybe that is the issue?
products.insertOne(item, function(err, r) {
console.log('item inserted')
res.redirect('/admin/addItems')
db.close();
});
Related
I start to develop a simple web application with NodeJS. and when I try to get a list record from SQL Server to show on the list page but somehow it's not working.
Here is the code :
const express = require("express");
const bodyParser = require("body-parser");
const sql = require("mssql");
const DBUtils = require("./DBUtils");
const app = express();
app.get("/all", (req, res, next) => {
let mypromise = new Promise((reso, rej) => {
let nameList = DBUtils.getNameList(sql);
if (nameList !== null || typeof nameList !== "undefined") {
reso(nameList);
} else {
rej("Error");
}
})
.then((result) => {
res.send(result);
})
.catch((err) => {
console.log(err);
});
});
app.get("/", (req, res, next) => {
console.log("the / route");
res.send("<h1>Hello to NodeJS</h1>");
});
app.listen(5003);
My DBUtils
const config = {
user: "sa",
password: "123",
server: "DESKTOP-7KGJI7L", // You can use 'localhost\\instance' to connect to named instance
database: "java",
options: {
encrypt: false,
},
};
const getNameList = (sql) => {
let nameList = "";
let errorString = "";
// Create connection
sql.connect(config, function (err) {
// Err
if (err) {
console.log(err);
}
// Create Request object
let sqlRequest = new sql.Request();
// QueryString
let queryString = `select * from NAME`;
// Run the query
sqlRequest.query(queryString, (err, data) => {
if (err) console.log(err);
//console.log(data); //data.recordset(array)[index].name
data.recordset.forEach((el) => {
nameList += `<li>${el.name}</li>`;
});
return nameList;
});
});
};
exports.getNameList = getNameList;
I pretty sure something wrong in Promise line but don't know how to fix it. Any suggest?
I think you are a newbie in Nodejs You made a common mistake. You did not use promise pattern correctly. Also, no need to pass next callback unless required.
Change getNameList as below :
const getNameList = (sql) => {
let nameList = "";
let errorString = "";
// Create connection
return new Promise (function(resolve,reject) {
sql.connect(config, function (err) {
// Err
if (err) {
console.log(err);
reject(err)
}
// Create Request object
let sqlRequest = new sql.Request();
// QueryString
let queryString = `select * from NAME`;
// Run the query
sqlRequest.query(queryString, (err, data) => {
if (err) {console.log(err)
reject(err)
}
//console.log(data); //data.recordset(array)[index].name
data.recordset.forEach((el) => {
nameList += `<li>${el.name}</li>`;
});
resolve(nameList);
});
});
})
};
Change app.get("/all") as below:
app.get("/all", (req, res) => {
DBUtils.getNameList(sql).then(function(list) {
res.status(200).send(list)
}).catch(function(err) { //handle error here
res.status(500)
})
})
Moreover, learn how to use promises and async-await.
Use appropriate body-parser as per requirement ie json, text etc.
Learn how and when to use next
I'm new to Node.js and am trying to pass some data from my DB model back to the router but I'm unable to find a solution. I have the following route file that makes a call to model:
Route file:
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password);
res.sendStatus(200);
});
Model file:
var db = require('../db.js');
module.exports.checkPassword = function(cust_id, password) {
var sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
result = res[0].Password;
if (err) throw err
});
};
My question is: how could I pass the queried result Password back to my Route file so that I can do this:
console.log('Password is', result);
I appreciate any help on this.
I'd use a promise
Model file
module.exports.checkPassword = function(cust_id, password) {
return new Promise(function(resolve, reject) {
const sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
if (err) return reject(err)
result = res[0].Password;
return resolve(result);
});
});
};
Route file
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password)
.then((result) => {
// DO: something with result
res.status(200).send();
})
.catch(console.log); // TODO: Handle errors
});
With async/await
router.post('/', async function(req, res) {
try {
const result = await customers.checkPassword(req.body.cust_id, req.body.password)
// DO: something with the result
} catch (e) {
console.log(e); // TODO: handle errors
} finally {
res.status(200).send();
}
});
I assume console.log('Password is', result); is just for test prupose, obviously you should never log a password! Also I suggest to move the callbabck of the routes do a different module, to improve code redability.
You might also find useful promise-module module on npm, basically a promise wrapper around mysql.
You can delegate the credential control to another function in your DB file where you can decide on what kind of data you want to return on success and failure to find such data. Then you can access it from where you are calling it.
I am trying to fetch data from couch and i follwed the code below
var request = require('request')
var nano = require('nano')('http://localhost:5984/user');
var url = 'http://127.77.3.1:5984/'
var db = 'users2/'
var id = 'document_id'
exports.insertdata = function (req, res) {
var data = req.body;
var item = {
name: data.name,
skills: data.skills,
experience: data.experience
};
nano.insert(item,(err, result) => {
if(!err){
//awesome
}if(result){
console.log(result)
response = {status:'success',data:result};
}
res.send(response);
});
};
exports.getdata = function (req, res) {
nano.getDoc('25f2b6d1e5b83887a42c74bc9b000647',(err, result) => {
if(!err){
//awesome
console.log(err)
}if(result){console.log(result)
console.log('inserted')
response = {status:'success',data:result};
}
res.send(response);
});
};
I am getting the following error
nano.getDoc is not a function
I am trying to fetch data from couch and i follwed the above code,i am not sure about the commands ....can anyone please suggest me some help..........
There is no getDoc in nano as far as I know. There is get. Maybe try changing this:
nano.getDoc('25f2b6d1e5b83887a42c74bc9b000647', (err, result) => {
});
to:
nano.get('25f2b6d1e5b83887a42c74bc9b000647', (err, result) => {
});
and see if that works.
For example here is a simplest query to the CouchDB database that powers the npm registry:
var nano = require('nano');
var db = nano('https://skimdb.npmjs.com/registry');
db.get('rsp', (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
Here rsp is the document id, which is a module's name on npm.
In your case it might work if you change getDoc to get. For other function names see the documentation at:
https://www.npmjs.com/package/nano
My document is not getting deleted from the collections. Iam also not getting any error. The http transaction is perfectly fine.
// Node Module dependencies
var express = require('express');
var router = express.Router();
// Local Module dependencies
var common = require('./common.js');
//var request = require('request');
var db =common.conn;
var Question = require('../model/questions');
router.route('/postquestion')
.post(function (req, res) {
var item = new Question(req.body);
//console.log(item);
//=======calling postdata method=====//
postQuestion(item, function (result) {
res.json(result);
});
});
router.route('/deletequestion')
.delete(function (req, res) {
console.log(req.body._id);
Question.collection.deleteOne({_id:req.body._id},function(err,question){
if(err) throw err;
console.log('the document is deleted')
res.send(question);
});
})
function postQuestion(item, fn) {
item.save(function (err) {
if (err) console.log(err);
fn(item);
});
}
module.exports = router;
postquestion function is working perfectly fine and the database is getting updated. When i use postman for raising a delete request and send the below json.
{
"_id": "57bc442c4925180b067f075b"
}
iam getting a response like the below.
{
"ok": 1,
"n": 0
}
When i check the database in robomongo i see the document is not deleted. Am i missing something to be done. Is there anything else to be done.....!
MongoDB uses ObjectID to index document.
If you want to delete object using Mongo ID you have to instanciate an ObjectID.
https://docs.mongodb.com/manual/reference/method/db.collection.deleteOne/
var ObjectID = require('mongodb').ObjectID;
router.route('/deletequestion')
.delete(function (req, res) {
console.log(req.body._id);
const _id = new ObjectID(req.body._id);
Question.collection.deleteOne({_id:_id},function(err,question){
if(err) throw err;
console.log('the document is deleted')
res.send(question);
});
})
if nothing works, try the following...
app.delete("/api/posts/:id",(req,res,next)=>
{
Post.deleteOne({_id: req.param.id})
.then(result=>{
console.log(result);
});
//console.log('Post Deleted on node JS');
res.status(200).json({message: 'Delete'});
});
If you are using MongooseJS, you just need to do Question.deleteOne({...}), you don't need to do theQuestion.collection...` thing. Unless you have stuff wired up differently in your Model
I'm trying to return the JSON data in a mongoose document, and then display it using Angular. There's no errors on the page when using this code. The $http.get method in the Angular IndexCtrl never makes it to success, which leads me to believe the problem is how I'm implementing the API get method. Any help rewriting that method to return properly greatly appreciated!
To clarify: what I want is to be able to access the document like a JSON Object so I can display the data to the client.
update: it does produce the error:
GET http://localhost:3000/api/tracks
It takes a while for that error to show in the console
the api method
app.get("/api/tracks", function(req, res) {
return Track.find({}, function (err, tracks) {
if (err) {
res.send(500);
return;
}
return res.json({
tracks: tracks
});
});
});
the mongoose database
var mongoose = require('mongoose');
var uristring =
process.env.MONGOLAB_URI ||
'mongodb://localhost/HelloMongoose';
var mongoOptions = { db: { safe: true }};
var db = mongoose.createConnection(uristring, mongoOptions, function (err, res) {
if (err) {
console.log ('ERROR connecting to: ' + uristring + '. ' + err);
} else {
console.log ('Succeeded connected to: ' + uristring);
}
});
//a Schema for a track
var Schema = new mongoose.Schema({
name: String,
location: String,
description: String
});
var Track = mongoose.model('Track', Schema);
var spot = new Track({name: 'zildjian'});
spot.save(function (err) {
console.log('saved');
if (err) // ...
console.log('meow');
});
The Angular controller
function IndexCtrl($scope, $http) {
$http.get('/api/tracks').
success(function(data, status, headers, config) {
$scope.tracks = data.tracks;
console.log($scope.tracks + "scope tracks data"); //This does not log! it never makes it this far
});
}
The Jade template that displays $scope.tracks
p There are {{tracks.length}} posts
div(ng-repeat='track in tracks')
h3 {{track.name}}
div {{track.description}}
I was not pulling the entries from the model correctly. Here is how I fixed it:
app.get("/api/tracks", function (req, res) {
var track = [];
var Track = mongoose.model('Track', trackSchema);
Track.find({}, function (err, records) {
records.forEach(function (post, i) {
track.push({
id: i,
title: post.title,
text: post.text.substr(0, 50) + '...'
});
});
res.json({
track: track
});
});
};
}