How to fetch data from mongodb using nodejs, expressjs - javascript

Here is my code
file name student.js
var mongoose = require('mongoose');
var studentSchema = new mongoose.Schema({
name:{
type: String,
required: true
},
rollno:{
type: Number,
required: true
},
grade:{
type: String,
required: true
},
result:{
type: String,
required: true
}
});
var Student = module.exports = mongoose.model('Student',studentSchema);
module.exports.getStudents = function (callback){
Student.find(callback);
}
**filename app.js**
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var PORT= process.env.PORT || 3000;
Student = require('./models/student');
mongoose.connect('mongodb://localhost/register');
var db= mongoose.connection;
app.get('/api/student', function (req,res){
Student.getStudents(function (err, student){
if(err){
throw err;
}
res.json(student);
});
});
app.listen(PORT);
console.log('Running app on port:' + PORT);

If you have an existing collection that you want to query using Mongoose, you should pass the name of that collection to the schema explicitly:
var studentSchema = new mongoose.Schema({ ... }, { collection : 'student' });
If you don't, Mongoose will generate a collection name for you, by lowercasing and pluralizing the model name (so documents for the model Student will be stored in the collection called students; notice the trailing -s).
More documentation here.

Related

My node js code has no effect on the keyword "require"

I am beginner studying node.js, REST API and MongoDB by following some online resources. I tried to use the keyword "require" in my following code so that the users are not allowed to input blank value:
ninjas.js (create schema and models)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//create Schema and model
const NinjaSchema = new Schema({
name:{
type: String,
require: [true,'Name field is required']
},
rank:{
type: String,
require: [true,'This field is required']
},
available:{
type: Boolean,
default: false,
require: [true,'This field is required']
}
//add in geo loction
});
const Ninja = mongoose.model('hi ninja',NinjaSchema);
module.exports = Ninja;
Below is the code handling the API:
api.js
const express = require('express');
const Ninja = require('../models/ninjas');
const router = express.Router();
//get a list of ninjas from the database
router.get('/ninjas',(req,res,next)=>{
res.send({type: 'GET'});
})
//add a new ninjas to the database
router.post('/ninjas',(req,res,next)=>{
//create a Ninja object and save it to DB
Ninja.create(req.body).then((ninja) => {
res.send(ninja)
}).catch(next);
})
//update a ninjas in the database
router.put('/ninjas/:id',(req,res,next)=>{
res.send({type: 'PUT'});
})
//delete a ninjas from the database
router.delete('/ninjas/:id',(req,res,next)=>{
res.send({type: 'DELETE'});
})
module.exports = router;
Below is the main program:
index.js
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
//set up express app
const app = express();
//connect to mondodb
mongoose.connect("mongodb://localhost/ninjago",{
useNewUrlParser: true,
useUnifiedTopology: true,
});
mongoose.Promise = global.Promise;
//body parser middleware
app.use(bodyParser.json());
//initialize routes
app.use('/api',require('./routes/api'));
//error handling middleware
app.use((err,req,res,next) => {
//console.log(err);
res.status(422).send({error: err.message});
});
//listen for requests
app.listen(process.env.port || 4000,() => {
console.log('now listening for requests');
});
However, when I tried to use POSTMAN to test the API, I found that even I did not some parameter, the system would still return a successful message.
May I know if there is something wrong or missing in my code causing the "require" keyword not working? Thank you so much!
Hon
Replace require with the keyword required in your schema
const NinjaSchema = new Schema({
name:{
type: String,
required: [true,'Name field is required']
},
rank:{
type: String,
required: [true,'This field is required']
},
available:{
type: Boolean,
default: false,
required: [true,'This field is required']
}
//add in geo loction
});
See this for reference.

Did you try nesting Schemas? You can only nest using refs or arrays

I'm trying to link my mlab with my models but it's throwing me an error like this:
throw new TypeError('Undefined type ' + name + 'at' + path +
^
TypeError: Undefined type undefined at required
Did you try nesting Schemas? You can only nest using refs or arrays.
In my folder models I've got:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ProjectSchema = new Schema({
name: String,
email: String,
description: String,
image: {data: Buffer, contentType: String },
date: { type: Date, default: Date.now },
location: String, //{street: String, number: String, zip: String, city: String, required: true},
fixedAmount: Number, required: true,
wantedAmount: Number,
receivedAmount: Number
});
module.exports = mongoose.model('Project', ProjectSchema);
and almost the same with my UserSchema...
I have also an index.js there :
const mongoose = require('mongoose');
module.exports.connect = (uri) => {
mongoose.connect(uri);
// plug in the promise library:
mongoose.Promise = global.Promise;
mongoose.connection.on('error', (err) => {
console.error(`Mongoose connection error: ${err}`);
process.exit(1);
});
// load models
require('./user');
require('./project');
require('./common');
};
In my server.js :
const config = require('./config.js');
// connect to the database and load models
require('./server/models').connect(config.dbUrl);
and in my config.js:
const dotenv = require('dotenv').config();
module.exports = {
'port': process.env.PORT || 5000,
'dbUrl': `mongodb://${process.env.USER_DB}:${process.env.PASSWORD_DB}#ds123930.mlab.com:23930/kickass`,
"jwtSecret": "a secret phrase !"
}

print Json from mongoDB

I tried to print my json from mongoDB.
I have one file(index.js) that call to function(getAllStudent) that exists in other file (student.js)and need to print my json, but it dosent work. when i run it in URL (in web page) its said me:"Cannot GET /getAllStudent".
My code:
index.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://db_usr:db_p');
var conn=mongoose.connection;
conn.on('error',function(err){
console.log('connection error'+err);
});
conn.once('open',function(){
console.log('connected.');
mongoose.disconnect();
});
student.js
var express=require('express');
var app=express();
var fs=require('fs');
var mongoose = require('mongoose');
var schema = mongoose.Schema;
var userSchema = new schema({
name:{type:String},
id: Number,
grade: Number,
year: Number,
coures:{type:String}
}, {collection: 'json'});
var User= mongoose.model('student',userSchema);
module.exports=User;
//return all students in json
module.exports = function(app) {
app.get('/getAllStudent', function(req,res) {
student.find({},function(err,user){
if(err) throw err;
console.log(User);
mongoose.disconnect();
});
})

MongoDB (Mongoose) make array part of schema

I'm creating a chat application with MongoDB (mongoose) and Nodejs. As you see below I have a schema as mongoose allows but my users in storeSchema needs to be an array of Strings (usernames). Is this the proper way to do it?
"use strict";
var express = require('express');
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
user: String
});
var messageSchema = new mongoose.Schema({
msg: String
});
var storeSchema = new mongoose.Schema({
users: [userSchema], // needs to be an array of users
channels: {
general: {
messages: [messageSchema]
},
videogames: {
messages: [messageSchema]
},
programming: {
messages: [messageSchema]
},
other: {
messages: [messageSchema]
}
}
});
var User = mongoose.model('User', userSchema);
var Message = mongoose.model('Message', messageSchema);
var Storage = mongoose.model('Storage', storeSchema);
module.exports = {
User: User,
Message: Message,
Storage: Storage
}
If you want users to be an array of username strings, then define it in storeSchema as:
users: [String]

Mongoose error: Schema hasn't been registered for model when populate

I am trying to join two collections and being able to get the combined data. To do so using Mongoose, i am supposed to use the populate syntax to achieve that. I am receiving error that the Schema Schema hasn't been registered for 'User_Fb'. From my code, I have exported the models and required in my server.js but the error is still appearing. What have I done wrong?
feed_post.model.js
var mongoose = require('mongoose');
var conn_new_app = mongoose.createConnection('mongodb://localhost/new_app');
var User_fb = require('../models/fb_db.model');
var Schema = mongoose.Schema;
var feed_postSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User_Fb' },
content: String,
location: String,
image: [{ type : String }]
});
var Feed_Post = conn_new_app.model('Feed_Post', feed_postSchema);
module.exports = Feed_Post;
fb_db.model.js
var mongoose = require('mongoose');
var conn_new_app = mongoose.createConnection('mongodb://localhost/new_app');
var Feed_Post = require('../models/feed_post.model');
var user_fb = new mongoose.Schema({
name: String,
location: String,
fb_id: Number
});
var User_Fb = conn_new_app.model('User_Fb', user_fb);
module.exports = User_Fb;
server.js
var express = require('express'),
mongoose = require('mongoose'),
User = require('./app/models/user.model'),
Post = require('./app/models/post.model'),
Maptest = require('./app/models/maptest.model'),
Feed_Post = require('./app/models/feed_post.model'),
User_Fb = require('./app/models/fb_db.model'),
app = express();
app.get('/testget', function(req,res){
Feed_Post.findOne().populate('user_id').exec(function(err, c) {
if (err) { return console.log(err); }
console.log(c.fk_user.userName);
});
});
UPDATED from Pier-Luc Gendreau Answer's
fb_db.model.js
module.exports = function (connection) {
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var user_fb = new mongoose.Schema({
name: String,
location: String,
fb_id: Number
});
return connection.model('User_FB', user_fb);;
}
feed_post.model.js
module.exports = function (connection) {
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var feed_postSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User_Fb' },
content: String,
location: String,
image: [{ type : String }]
});
return connection.model('Feed_Post', feed_postSchema);;
}
server.js
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
conn_new_app = mongoose.createConnection('mongodb://localhost/new_app'),
User_Fb = require('./app/models/fb_db.model')(conn_new_app),
Feed_Post = require('./app/models/feed_post.model')(conn_new_app);
app.get('/testget', function(req,res){
Feed_Post.find().populate('user_id').exec(function(err, res) {
if (err) { return console.log(err); }
console.log(res);
});
});
This is all I had to do Customer.findOne({}).populate({ path: 'created_by', model: User }) instead of this Category.findOne({}).populate({'author'})
IF YOU (really) USE MULTIPLE mongoDB CONNECTIONS
I do realise that this is not the case for the OP, but if you genuinely use multiple connections you MUST provide the model when using .populate(), as mongoose will only "find" models on the same connection.
ie where:
var db1 = mongoose.createConnection('mongodb://localhost:27017/gh3639');
var db2 = mongoose.createConnection('mongodb://localhost:27017/gh3639_2');
var userSchema = mongoose.Schema({
"name": String,
"email": String
});
var customerSchema = mongoose.Schema({
"name" : { type: String },
"email" : [ String ],
"created_by" : { type: mongoose.Schema.Types.ObjectId, ref: 'users' },
});
var User = db1.model('users', userSchema);
var Customer = db2.model('customers', customerSchema);
Correct:
Customer.findOne({}).populate('created_by', 'name email', User)
or
Customer.findOne({}).populate({ path: 'created_by', model: User })
Incorrect (produces "schema hasn't been registered for model" error):
Customer.findOne({}).populate('created_by');
The problem is that you are creating a new connection in each and every model, so you end up with a bunch of different connection objects. Even though they are pointing to the same database, mongoose models don't know about other connections. You should instead create the connection object in your main app and then pass it around.
server.js
var express = require('express');
var mongoose = require('mongoose');
var app = express();
var conn_new_app = mongoose.createConnection('mongodb://localhost/new_app');
var Feed_Post = require('./app/models/feed_post.model')(conn_new_app);
app.get('/testget', function(req,res){
Feed_Post.findOne().populate('user_id').exec(function(err, c) {
if (err) { return console.log(err); }
console.log(c.fk_user.userName);
});
});
Then modify your models so they are actually a function:
feed_post.model.js
module.exports = function (connection) {
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var feed_postSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User_Fb' },
content: String,
location: String,
image: [{ type : String }]
});
return connection.model('Feed_Post', feed_postSchema);;
}
Also, like Adrian mentions, you can use mongoose as a singleton. However, I do recommend using createConnection as you did because if you ever need a second connection, you won't have to refactor the connection code to your first database.
It looks like you are creating a different database connection for each model, which isolates the models from each other. Mongoose must assume this isolation, because they could exist on different databases or even database servers.
Try connecting once, and just calling mongoose.model() instead of connection.model() when defining your models. Mongoose is a singleton by default.
In my case, this issue because I haven't included the ref model into the application.
You can get the field you want by using select
Example to get the email of the customer:
Customer.findOne({}).populate({ path: 'created_by', model: User, select: 'email' })
More Details in mongoose documentation

Categories