Am merging 2 different applications one is an authentification app and the other is a todo app where user input data and the app displays it. The two work fine seperately. when i merged them there is a parse error on the second app; I think i got the issue. the authentification app uses app.use(bodyParser.json()); and the second one uses app.use(bodyParser()); I think there is a conflict but i dont know how to solve it can you help
here is my api
var Meetup = require('./models/meetup');
module.exports.create = function (req, res) {
var meetup = new Meetup(req.body);
console.log(req.body);
meetup.save(function (err, result) {
console.log(result);
res.json(result);
});
}
module.exports.list = function (req, res) {
Meetup.find({}, function (err, results) {
res.json(results);
});
}
console.log(req.body) displays undefined.
console.log(result) displays { __v: 0, _id: 583464c837cb810e045b1825 } while it should display { __v: 0,name:'text input' _id: 583464c837cb810e045b1825 }
here is my schema model :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Meetup = new Schema({
name: String,
text:String,
});
module.exports = mongoose.model('Meetup', Meetup);
The bodyParser() constructor is deprecated.
You should use this instead:
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
Related
I'm currently learning about APIs. I'm using Dev Ed's video on a RESTful MERN API. I set up my routes and I could successfully connect to my MongoDB database. However, when attempting to call save() on a post to the DB, I was returned my error message, a JSON object with a message containing the err, but my err object was completely empty.
posts.js:
const express = require('express');
const router = express.Router();
const Post = require('../models/Post');
router.get('/', (req, res) => {
res.send('We are on /posts!');
});
router.post('/', (req, res) => {
const post = new Post({
title: req.body.title,
desc: req.body.desc,
});
post.save()
.then(data => {
res.json(data);
})
.catch(err => {
res.json({ message: err });
});
});
module.exports = router;
app.js:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
require('dotenv/config');
const app = express();
const PORT = 8080;
app.use(bodyParser.json());
// Import Routes ------------------------
const postsRoute = require('./routes/posts');
app.use('/posts', postsRoute);
// ROUTES --------------------------------
app.get('/', (req, res) => {
res.send('We are home!');
});
mongoose.connect(
process.env.DB_CONN,
{ useNewUrlParser: true },
() => {
console.log('Succesfully connected to DB!')
});
app.listen(PORT);
Post.js (schema):
const mongoose = require('mongoose');
const PostSchema = mongoose.Schema({
title: {
type: String,
required: true,
},
desc: {
type: String,
required: true,
},
date: {
type: Date,
default: Date.now,
}
});
module.exports = mongoose.model('Posts', PostSchema);
My POST request and response (Postman):
In my code, I am attempting to send the new Post to my DB, but instead I get an error, an empty one. I either need to figure out how to view my error correctly (so that's it's not empty) or the larger problem: why my POST request is failing.
Again, I am learning about APIs, this is my very first time writing one. If there's anything I missed (like other code that you would need) or if there's something I should be doing differently, please, let me know! Thank you in advance!
use status when you want to use res like this:
for success result
res.status(200).json(data);
for .catch
res.status(500).json({ message: err });
but I prefer use async/await with try/cacth like this:
router.post('/', async(req, res) => {
const post = new Post({
title: req.body.title,
desc: req.body.desc,
});
try {
let data = await post.save()
res.status(200).json(data)
} catch (error) {
res.status(500).json({ message: error});
}
});
check the documentation of promises in mongnoos
check the connection of mongoose like this:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
require('dotenv/config');
const app = express();
const PORT = 8080;
app.use(bodyParser.json());
// Import Routes ------------------------
const postsRoute = require('./routes/posts');
app.use('/posts', postsRoute);
// ROUTES --------------------------------
app.get('/', (req, res) => {
res.send('We are home!');
});
runMongoose()
app.listen(PORT);
async function runMongoose(){
try {
await mongoose.connect(
process.env.DB_CONN,
{ useNewUrlParser: true }
);
console.log("mongodb is OK");
} catch (error) {
console.log("mongodb Warning", error);
}
}
if Succesfully connected to DB! printed mongoose connection is OK
the problem is that you added
{ useNewUrlParser: true }
remove that and it's gonna work fine ;)
I am creating a MERN stack application and have chosen to use mongoose to communicate with MongoDB Atlas. But MongoDB Atlas uses clusters with databases inside which again has collections. I cant find any documentation for how to connect to a specific database and collection.
this is my current code:
File with the schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
User: {
fisrtname: String,
lastname: String,
email: String,
password: String,
},
Todos: [
{
title: String,
completed: Boolean,
id: Schema.Types.ObjectId,
},
],
});
module.exports = mongoose.model('User', userSchema, 'todosCollection');
Main server file
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const dbConfig = require('./database/db');
const app = express();
const PORT = process.env.PORT || 8080;
// Connecting to MongoDB database
mongoose.Promise = global.Promise;
mongoose
.connect(dbConfig.db, {
useNewUrlParser: true,
})
.then(
() => console.log('Database Sucsessfully connected!'),
err => console.error('Could not connect to database: ' + err)
);
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.use('/api/todos', require('./routes/api/todos'));
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
And the function who searches MongoDB
! This is a snippet from another file but the rest is unimportant to the question.
const userSchema = require('../../database/models/User');
router.get('/', (req, res) => {
userSchema.find((err, data) => {
if (err) {
res.staus(500).json({ msg: 'Did not found database data' });
} else {
res.json(data);
}
});
});
Once you have connected with your Atlas MongoDB cluster - you can treat it the same as any other MongoDB connection. See my answer on how to correctly connect to an Atlas cluster: https://stackoverflow.com/a/61480485/8322220.
However, you also seem to be having an issue querying your data, but it is hard to help without the relevant code.
However, in your 3rd snippet, you are querying User - but I think your User schema is not correct.
I suggest that you separate Todos into its own Schema and export separately to User i.e:
module.exports = mongoose.model('Todo', todoSchema)
By passing dbname as options parameter you can specify the database,
check out the link for clarity.
https://mongoosejs.com/docs/connections.html#options
I have some code which uses some data from the database: Assignment and the Collection: todolist, which is supposed to interact with MongoDB and to add, delete or list the JSON in the collection.
To understand the problem I have to show the code before I explain it.
Here is the code for the model:
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TaskSchema = new Schema({
id: {
type: String,
unique: true
},
desc: {
type: String
}
});
module.exports = mongoose.model('Task', TaskSchema);
Here is the code for the controller:
'use strict';
var mongoose = require('mongoose'),
Task = mongoose.model('Task');
exports.list_all_tasks = function(req, res) {
console.log("listing should commence");
Task.find({}, function(err, task) {
if (err)
res.send(err);
return;
res.json(task);
});
};
exports.create_a_task = function(req, res) {
var new_task = new Task(req.body);
new_task.save(function(err, task) {
if (err)
res.send(err);
return;
res.json(task);
});
};
exports.delete_a_task = function(req, res) {
Task.deleteOne({
_id: req.params.taskId
}, function(err, task) {
if (err)
res.send(err);
return;
res.json({n: task.n, ok: task.ok});
});
};
Here is the code for the route:
'use strict';
module.exports = function(app) {
var todoList = require('./controller');
// todoList Routes
app.route('/tasks')
.get(todoList.list_all_tasks)
.post(todoList.create_a_task);
app.route('/tasks/:taskId')
.delete(todoList.delete_a_task);
};
Server.js file:
const express = require('express');
const app = express();
const port = 3000;
var mongoose = require('mongoose');
Task = require('./api/model'); //created model loading here
bodyParser = require('body-parser');
mongoose.Promise = global.Promise;
const controller = require('./api/controller');
// mongoose instance connection url connection
//P.S The username and password have been taken off this security and privacy reasons
mongoose.connect('mongodb+srv://userName:password#server-4tjvi.mongodb.net/Assignment?retryWrites=true', { useNewUrlParser: true });
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./api/routes'); //importing route
routes(app); //register the route
app.listen(port);
console.log('Welcome to Just Do It, your Node.js application for all your To Do List needs.');
console.log('todo list API server has started on: port ' + port);
Ok so the problem that I have is that when I type in localhost:3000/tasks into Postman, it says it is loading for a long time and then it says it could not get a response. What I want it to do is to list all the tasks (JSON) from the collection onto postman.
I have set up MongoDB, I have downloaded everything that is required as well; mongoose, nodemon, Mongodb, etc.
And how do I upload things from my node application to the database collection.
The problem in your code is with syntax. Consider the following code (out of the several)
Task.find({}, function(err, task) {
if (err)
res.send(err);
return;
res.json(task);
});
In this block of code your Task.find is going to return undefined and res.json is never reached. And since your server does not send any response, the request is just going to time-out.
Just because return is indented doesn't mean it's part of if block. To make it a part of if block you've to put it in braces {}
Here's an illustration:
function test() {
let out;
if (true)
out === 'yes';
return; // <-- not part of if block
console.log('never reached')
return out; // <-- never reached
}
console.log(test())
The above is equivalent to:
function test(x) {
let out;
if (true)
out === 'yes';
return; // return undefined
}
console.log(test())
So refactoring it:
Task.find({}, function(err, task) {
if (err) {
res.send(err);
return;
}
res.json(task);
});
Or return res.send
Task.find({}, function(err, task) {
if (err)
return res.send(err);
res.json(task);
});
I have several mongodb collections,
Fruits: [ {}, {}, {} ...],
Bread: [{}, {}, {} ...]
I want to use dynamic collection name in my server like
// :collection will be "Fruits" or "Bread"
app.get('/fetch/:collection', function (req, res){
[req.params.collection].find({}, function(err, docs){
res.json(docs)
})
})
But as you know, [req.params.collection].find()... isn't working. How can I use dynamic collection name?
You can use the different collections using
db.collection('name').find({})
Here is the code i have tried
App.js
const express = require('express');
const bodyParser = require('body-parser');
const MongoClient = require("mongodb").MongoClient;
const assert = require('assert');
const url = 'mongodb://localhost:27017';
var db;
MongoClient.connect(url, { useNewUrlParser: true }, function (err, client) {
assert.equal(null, err);
console.log("Connected successfully to DB");
db = client.db('name of the db');
});
var app=express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/test/:collection', function(req,res){
let collection = req.params.collection;
console.log(collection);
db.collection(collection).find({}).toArray( function (err, result) {
res.send(result);
});
});
var port = 8000
app.listen(port, '0.0.0.0', () => {
console.log('Service running on port ' + port);
});
Hope this helps
This is not working as the collection name you are passing is just a variable with no DB cursor.
Here's what you can do here:
Create an index.js file, import all the models in that file with proper names as keys.
eg:
const model = {
order: require("./order"),
product: require("./product"),
token: require("./token"),
user: require("./user")
}
module.exports = model;
Let's assume your request URL is now.
/fetch/user
Now import this index.js as model in your controller file.
eg:
const model = require("./index");
Now you can pass the key as params in your request like and use like it is stated below:
app.get('/fetch/:collection', function (req, res){
model[req.params.collection].find({}, function(err, docs){
res.json(docs) // All user data.
})
})
Hope this solves your query!
I will give solution for this but I don't know is this as per developer standards
let your model names, fruit.js and bread.js in model folder
app.get('/fetch/:collection', function (req, res){
let collectionName = require(`./models/${req.params.collection}`)
collectionName.find({}, function(err, docs){
res.json(docs)
})
})
Hope this will work
I made this node js app and then i tried with postman but every time i made a request that involves mongodb, it keeps loading. The function find of the model is where the code stops and the callback is never called.
app.js
var express = require("express"),
app = express(),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
mongoose = require('mongoose');
//Connection to DB
mongoose.connect('mongodb://localhost:27017/users', function(err, res) {
if(err) {
console.log('ERROR: connecting to Database. ' + err);
}
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
var models = require('./models/user')(app, mongoose);
var userContoller = require('./controllers/user');
var router = express.Router();
router.get('/', function(req, res) {
console.log('GET');
res.send("Hello World!");
});
app.use(router);
var users = express.Router();
users.route('/users')
.get(userContoller.findAllUsers);
app.use('/api', users);
app.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});
models/user.js
exports = module.exports = function(app, mongoose){
var userSchema = new mongoose.Schema({
userName: { type: String },
password: { type: Number }
});
mongoose.model('User', userSchema);
};
controllers/user.js
var mongoose = require('mongoose');
var User = mongoose.model('User');
//GET - Return all tvshows in the DB
exports.findAllUsers = function(req, res) {
console.log('llega');
User.find(function(err, users) {
if(err) res.send(500, err.message);
console.log('GET /users')
res.status(200).jsonp(users);
});
};
The mongodb server is started through the console but i don't know how to check it.
Thanks!
EDIT:
I made the code easier for me to test and solve the problem.
The code now is this and im not getting the connection to mongodb.
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', function() {
console.log('error');
});
db.once('open', function() {
console.log('connected');
});
I don't get in the console the error or the connected.
In the mongod console i get some messages saying that a new connection was made. This happens every time i open the nodejs program.
Thanks
I think the problem is that you are giving call back to the mongoose.connect function. In my case i did:
mongoose.connect(url, options)
const db = mongoose.connection
db.on('error', function () { console.log('Cannot Connect to DB') })
db.once('open', function () { console.log('Mongoose Connected to DB') })
Also instead of:
users.route('/users').get(userContoller.findAllUsers);
You may try:
users.get('/users', userController.findAllUsers);
And I realized that you don't pass a next argument to your controller which express generally complains if you dont pass.
Edit: I think i found the error.
When you are using the .find function you need to pass 2 arguments. In your case because you are not passing the callback as the second argument it never gets called.
User.find({}, callback) should do it.
I found the problem.
The version of mongoose was older than the needed to connect to my mongodb version. Just update it via npm and good to go.