Express node.js with mongoose CRUD strange behavior. - node.js

I'm starting my adventure with NodeJS. I've choose express web framework with mongoose database. As part of my front-end I'm using AngularJS.
First the front end, basic form args passing to /api/user.
$scope.form = {};
$scope.submitUser = function () {
console.log($scope.form);
$http.post('/api/user', $scope.form).
success(function(data) {})
.error(function(data) {});
};
$scope.form equals to:
Object {name: "foo", surname: "bar", email: "foobar#bar.foo"}
Then we got the back-end, where I start with default user schema:
var userSchema = new mongoose.Schema({
name : String,
surname : String,
email : String
});
var User = mongoose.model('User', userSchema);
And the api post handler:
app.post('/api/user', function (req, res) {
User.create({
name : req.name,
surname : req.surname,
done : false
}, function(err, user) {
if (err)
res.send(err);
res.json(user);
});
});
And the result of that instead of object is just id with __v:
__v: 0
_id: "536e218351b1182d0f000001"
PS. This one is magic, I have completly no idea why this is happening:
Those records above __v and _id, are not being save anywhere (show collections, and find() on each of those results in null). But when I run
User.find(function(err, users) {
if (err)
res.send(err)
res.json(users);
I get few records (previous tries of passing this form) with it's __v and _id.
Connection looks like this:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:1/test');
Thanks for any tips, explanation to that. Sorry for my lack of knowledge but I really tried.
Have a nice day! ;)

Assuming that you send the json object in the body (payload) of POST from client, The server should access the value as req.body.name, not req.name
app.post('/api/user', function (req, res) {
User.create({
name : req.body.name,
surname : req.body.surname,
done : false
}, function(err, user) {
if (err)
res.send(err);
res.json(user);
});
});
Make sure you pass body-parser middleware to express:
var express = require('express')
var app = express()
app.use(express.bodyParser()); // for express 3.x
or for express 4.x
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser()); // for express 4.x

In my case it does not work. Why?
I am getting the value from req.body.name
If I log it console.log(req.body.name); I get the value on my console.
POST:
{ name: 'typing any name', status: null }
typing any name
So the workflow between my frontend (angular.js), the form and the backend (node.js, express, mongoose) seems to work. Now I POST the value, but I get an empty object in my mongoDB.
{"_id":"543a50a974de6e2606bd8478","__v":0}
app.post('/api/offers', function (req, res){
var offer;
console.log("POST: ");
console.log(req.body);
console.log(req.body.name);
offer = new OfferModel({
name: req.body.name,
value: req.body.value,
title: req.body.title,
content: req.body.content,
});
offer.save(function (err) {
if (!err) {
return console.log("created offer" + req.body.name);
} else {
return console.log(err);
}
});
return res.send(offer);
});
And here is the model:
var offerSchema = mongoose.Schema({
offer : {
name : String,
value : String,
title : String,
content : String,
image : String,
start : String,
end : String,
targets : String,
beacons : String,
published : String
}
});
var OfferModel = mongoose.model('Offer', offerSchema);

Related

Undefined: req.file() outputs undefined even when using upload.single() middleware

// Models
var mongoose = require('mongoose');
var ProfileSchema = new mongoose.Schema({
fullName: {
type: String,
required: true
}
// profileImage: {type: String, required: true}
});
module.exports = mongoose.model('Profile', ProfileSchema)
// Controllers
var Profile = require('../models/profile');
var multer = require('multer');
var upload = multer({dest: 'uploads/'});
exports.createProfile = (upload.single('profileImage'), function (req, res, next) {
var profileData = {
fullName: req.body.fullName,
// profileImage: req.file
}
console.log(req.file);
console.log('req.file: ', JSON.stringify(req.file));
console.log(profileData);
Profile.create(profileData, function (err, profile) {
if (err) {
// console.log(err);
res.end();
return;
// res.send(err);
}
Profile.create(function (err, profiles) {
if (err) {
res.end();
// res.send(err);
return;
}
res.json(profileData);
});
});
});
I'm trying to use middleware to add text and image at the same time in the MongoDB database. However, my fields aren't populated and when I try to print it out in the console it says req.file(): undefined. I've researched on the other issues and it states using 'upload.single()' will solve the problem. In my case, it didn't! The first section is my model view(Schema), the second section is my controllers' view.

NodeJS Mongoose not working properly

I have a problem with NodeJS and Mongoose. The connection to the DB stands but I can't get any data from there. I can connect to /api/buckets as well with no problems. Here is my code:
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
Bucket = require('./models/bucket');
// Connect to Mongoose
mongoose.connect('mongodb://localhost/worldbucket', function (err) {
if (err) throw err;
console.log('Successfully connected');
});
app.get('/', function (req, res) {
res.send('Please use sth other');
});
app.get('/api/buckets', function (req, res) {
Bucket.getBuckets(function (err, buckets) {
console.log("funkt");
if (err) {
throw err;
}
res.json(buckets);
});
});
app.listen(3000);
console.log('Running on port 3000');
and bucket.js:
var mongoose = require('mongoose');
// Bucket Schema
var bucketSchema = mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
creator: String,
text: String,
fulfilment: String,
latitude: Number,
longtitude: Number
});
var Bucket = mongoose.model('bucket', bucketSchema);
module.exports = Bucket;
// get Buckets
module.exports.getBuckets = (callback, limit) => {
Bucket.find(callback).limit(limit);
}
I hope you can help me.
Thanks in advance
Im not sure what version of mongoose you using, but from their docs
http://mongoosejs.com/docs/queries.html
// With a JSON doc
Person
.find({
occupation: /host/
})
.limit(10)
.sort({ occupation: -1 })
.select({ name: 1, occupation: 1 })
.exec(callback);
So in your case should be
Bucket.find({}).limit(limit).exec(callback);
Hope this helps.
Check the name of your collection in mongo - it should be called buckets not bucket. It needs to be plural. Apart from that your code works, I have tested it.👍🏻
> db
worldbucket
> db.buckets.insert({"creator":"me","text":"hello world"})
WriteResult({ "nInserted" : 1 })
> db.buckets.find()
{ "_id" : ObjectId("5a0a154a29642fd7a970420e"), "creator" : "me", "text" : "hello world" }
$ curl http://localhost:3000/api/buckets
[{"_id":"5a0a154a29642fd7a970420e","creator":"me","text":"hello world"}]
There is another SO thread on this topic here: Why does mongoose always add an s to the end of my collection name

Need to do a many comments belong to one article relation MongoDB

I am using Mongoose/MongoDB and I am trying to associate many comments to one article. My app begins by scraping from a website and then the user has the option to save each article that was scraped into the MongoDB. When the user chooses to save one article, I save it into database. So when a user clicks on one of their saved articles, they can comment on them. Each article has its own comment section I need to retrieve the correct comments.
//My post comment request in JS file
function postComment(){
var articleComment = {
comment: $('#comment').val().trim()
}
$.post('/comments/' + articleID, articleComment).done(function(data){
$('.main-popup').fadeOut();
console.log('DONNE', data);
});
}
//Post route in controller
router.post('/comments/:id', function(req, res){
var newComment = new Comment(req.body);
newComment.save(function(err, doc){
if(err){
console.log(err);
}else{
Comment.findOneAndUpdate({ "_id": doc._id }, { "article": req.params.id }).exec(function(err, doc){
if(err){
console.log(err);
res.send(err);
}else{
res.send(doc);
}
});
}
});
});
//Get request to get correct comments when clicked on specific article
function showCommentBox(){
$('.comments').empty();
$('#comment').val("");
articleID = $(this).attr('data-article-id');
$.get('/comments/' + articleID, function(data){
if(data.article){ //This is undefined*********************
for(var x = 0; x < data.comment.length; x++){
$('.comments').append("<div><h2>" + data.comment[x].comment + "</h2><span><button>×</button></span></div>");
}
}
$('.main-popup').fadeIn();
});
}
//Get route in controller
router.get('/comments/:id', function(req, res){
Comment.findOne({ "article": req.params.id }).populate("article").exec(function(err, doc){
if(err){
console.log(err)
}else{
res.json(doc);
}
});
});
//Article Model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ArticleSchema = new Schema({
title: {
type: String
},
link: {
type: String
},
description: {
type: String
},
img: {
type: String
}
});
var Article = mongoose.model("Article", ArticleSchema);
module.exports = Article;
//Comment Model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CommentSchema = new Schema({
comment: {
type: String
},
article: {
type: Schema.Types.ObjectId,
ref: 'Article'
}
});
var Comment = mongoose.model('Comment', CommentSchema);
module.exports = Comment;
First, you're missing $set when you do .findOneAndUpdate. Also I think you should convert a string to Mongo ObjectId before setting it.
So it might look likt this:
const ObjectId = mongoose.Types.ObjectId;
Comment.findOneAndUpdate({ "_id": doc._id }, {$set: {"article": new ObjectId(req.params.id) }})
Also you don't need to make 2 database calls. You could article id before saving newComment and then simply send it as a response like this:
//Please notice that mongoose.Schema.Types.ObjectId and mongoose.Types.Object are different types.
//You need this one here:
const ObjectId = mongoose.Types.ObjectId;
router.post('/comments/:id', function(req, res){
var newComment = new Comment(req.body);
newComment.article = new ObjectId(req.params.id);
newComment.save(function(err, doc){
if (err) {
console.error(err);
res.send(err);
return;
}
res.send(doc);
});
});

Expressjs + Mongoose - This webpage is not available?

Why mongoose crashes the expressjs site?
Below is my code:
var express = require('express');
var mongoose = require('mongoose');
var app = express();
// Connect to mongodb
mongoose.connect("mongodb://localhost/testdb", function(err) {
if (err) throw err;
console.log("Successfully connected to mongodb");
// Start the application after the database connection is ready
app.listen(3000);
console.log("Listening on port 3000");
});
// With Mongoose, everything is derived from a Schema. Let's get a reference to it and define our users.
var userSchema = mongoose.Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date
});
// The next step is compiling our schema into a Model.
var User = mongoose.model('User', userSchema);
// Set route.
app.get("/", function(req, res) {
// We can access all of the user documents through our User model.
User.find(function (err, users) {
if (err) return console.error(err);
console.log(users);
})
});
I get this on browser:
This webpage is not available
But in my terminal I get the result:
Successfully connected to mongodb
Listening on port 3000
[ { _id: 57682f69feaf405c51fdf144,
username: 'testuser1',
email: 'testuser1#testdomain.com' },
{ _id: 57683009feaf405c51fdf145,
username: 'testuser2',
email: 'testuser2#testdomain.com' },
{ _id: 57683009feaf405c51fdf146,
username: 'testuser3',
email: 'testuser3#testdomain.com' }]
Any ideas what I have missed?
The problem is that you are not writing anything in the response object in your request handler. Therefore the browser keeps waiting for the request to finish and ends up with a timeout. In your app.get(), you can update the response like this:
// Set route.
app.get("/", function(req, res) {
// We can access all of the user documents through our User model.
User.find(function (err, users) {
if (err) {
console.error(err);
// some simple error handling, maybe form a proper error object for response.
res.status(500).json(err);
}
console.log(users);
res.status(200).json(users); // setting the object as json response
//OR
// res.end(); if you don't want to send anything to the client
})
});
or something similar.
Refer the Express documentation for more details:http://expressjs.com/en/api.html#res

Node.js express download from mongodb

I want to write a rest api, with which i am able to download some data. All datas were stored in a mongodb. I don't know what to pass to the download method, to make it possible.
Here is my current code:
router.get('/download/:productId/:username/:token', function (req, res) {
var auth = require('../provider/authProvider.js');
var authInst = new auth();
authInst.checkAuth(req.params.username, req.params.token, res, function (err, obj) {
if (obj == true) {
res.status(200);
// here is my problem, what to pass to the download-method
res.download('');
}
});
});
I could not find anything else, than passing paths to the download method.
Does anyone has an idea how to solve my problem?
I assume you know how to set up mongoose environment, putting config, connecting to MongoDB. If not please refer to my answer here.
Now let's say we have a Document in MongoDB as Blog.
So we need to create a model for Blog so that we can do CRUD operations using Mongoose ORM.
you need mongoose module for this to be included in your project.
so run this command from your project root directory, it will automatically download mongoose for you.
npm install mongoose --save
BlogModel.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var BlogSchema = new Schema({
"title" : { type: String },
"user_id" : { type: String },
"blog_uri" :{ type: String },
"post_date" : { type : Date, default: Date.now},
"body" : { type: String, default: '' },
"comments" : [
{ 'content' : { type: String },
'user_id' : { type: String },
'comment_date' : { type: Date },
'votes' : [
{
'user_id' : { type: String }
}
]
}
],
"hidden" : {type:Boolean, default: false }
});
mongoose.model('Blog', BlogSchema);
So let's create a separate file called BlogController.js where we will write methods for CRUD.
var mongoose = require('mongoose');
var Blog = mongoose.model('Blog');
var ObjectId = require('mongoose').Types.ObjectId;
exports.create = function(req,res){
var blog = new Blog(req.body);
blog.save(function(err){
if(err)
res.json({message: "Error occured while saving"});
else{
res.redirect('/home');
}
});
};
exports.getAll = function(req,res){
Blog.find(function(err,blogs){
if(err){
res.send(err);
}else{
res.json(blogs);
}
});
};
exports.get = function(req,res){
var id ;
try{
id = new ObjectId(req.params.id);
Blog.findById(id,function(err,blog){
if(err){
res.send(err);
}else{
res.render('blog.ejs', {
blog: blog
});
}
});
}catch(e){
res.send(404);
}
};
exports.update = function(req,res){
var id ;
try{
id = new ObjectId(req.params.blog_id);
Blog.findById(id,function(err,blog){
if(err){
res.send(err);
}
blog.save(function(err){
if(err)
res.send(err);
res.render('blog.ejs', {
message: "Blog Updated successfully"
});
});
});
}catch(e){
res.send(404);
}
};
exports.delete = function(req,res){
var id ;
try{
id = new ObjectId(req.params.blog_id);
Blog.remove({_id:id},function(err,blog){
if(err){
res.send(err);
}
res.render('blog.ejs', {
message: "Blog deleted successfully"
});
});
}catch(e){
res.send(404);
}
};
So this was about CRUD using Mongoose. I usually don't use res.render(..) in my projects because i put Templating logic in front end. I just use res.json(..) and pass the json data to the the frontend. So please go ahead and try. I hope i answered your question. You can refer to
this repo, for better example. Here i got a very clean CRUD implementation.

Resources