Hi i am developing nodejs application with express and mongodb.So i must define mongoose and schema in my all routing js to use mongo and schema. I want to define them only ones. I am new at node.js so please be patient. My project structure:
My route.js is shown below:
var routes = function (app) {
app.locals.error=null;
app.get('/login', function (req, res) {
return res.render(__dirname + "/views/login", {
title: 'Giriş',
stylesheet: 'login'
});
});
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/fuatblog");
var UserSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
age: Number
}),
Users = mongoose.model('Users', UserSchema);
app.post('/sessions', function (req, res) {
console.log(req.body.login.email);
console.log(req.body.login.password);
console.log(req.body.login.rememberMe);
Users.find({
email: req.body.login.email,
password: req.body.login.password
}, function (err, docs) {
if (! docs.length) {
// no results...
console.log('User Not Found');
res.status(400);
return res.render(__dirname + "/views/login", {
title: 'Giriş',
stylesheet: 'login',
error: 'Kullanıcı adı veya şifre yanlış'
});
}
console.log('User found');
req.session.email = docs[0].email;
console.log(req.session.email);
return res.redirect('/Management');
});
});
};
module.exports = routes;
And my server.js(app.js)
/**
* Module dependencies.
*/
////Mongoose eklendi
var express = require('express'),
mongoose= require('mongoose');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
////Cookie için eklendi.
app.use(express.cookieParser());
////Session desteği için eklendi
app.use(express.session({secret: 'asdfsdfsafasdfasdfasdf'}));
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
////Put ve Delete mothodları için
app.use(express.methodOverride());
////Requeestleri ayrıştırmak için kullanılıyor
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
////Helpers
//require('./apps/helpers')(app);
//Routes
require('./apps/authentication/routes')(app)
require('./apps/blog/routes')(app)
require('./apps/management/routes')(app)
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
I'm going to assume that you meant that you want to define the Schema only ONCE.
What I like to do is to initialize all the models that I'm going to use when the server starts and the mongodb connection is established.
An ideal directory structure would be something like this:
mongodb
--schemas
----user.js
--models.js
You would put your schemas inside the schema folder, such as your User model:
(user.js)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = function() {
var UserSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
age: Number
});
mongoose.model("User", UserSchema);
};
In models.js, you would have code that initializes each schema model in the schemas directory.
(models.js)
exports.initialize = function() {
require("fs").readdirSync(__dirname + "/schemas").forEach(function(file) {
require('./schemas/' + file)();
});
};
In your app.js file, you would do this call to initialize all your schemas AFTER you establish your connection to mongoose:
require($pathToYourModelsJsFile).initialize();
After this, you are all set to use your models! All you have to do for when you want to use them is:
var mongoose = require('mongoose');
var User = mongoose.model('User');
// Do work
User.find();
Related
I have been trying to add authentication feature to my angular app using express and mongo and I am getting the following error on line app.js 9:1:
"Schema hasn't been registered for model "User""
'Use mongoose.model(name, schema)',
name: 'MissingSchemaError'
Following is my app.js:
require('dotenv').config();
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var passport = require('passport');
require('./app_server/models/db');
require('./app_server/config/passport'); ----> This line is the one thats throwing the error
var indexRouter = require('./app_server/routes/index');
var usersRouter = require('./app_server/routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'app_server','views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use('/', indexRouter);
app.use('/users', usersRouter);
Following is my passport.js:
var passport = require('passport');
var LocalStratergy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var User = mongoose.model('User'); ---> Probably the culprit
passport.use(new LocalStratergy({usernameField: 'email'},
function(username, password, done){
User.findOne({email: username}, function(err, user){
if (err) { return done(err); }
if (!user) {
return done(null, false, {
message: 'Incorrect Email.'
});
}
if (!user.validPassword(password)) {
return done(null, false, {
message: 'Incorrect Password.'
});
}
return done(null, user);
});
}
));
Following is my users.js:
var mongoose = require('Mongoose');
var crypto = require('crypto');
var jwt = require('jsonwebtoken');
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
fullname: {
type: String,
require: true
},
hash: String,
salt: String
});
Following is my db.js:
var mongoose = require('Mongoose');
var dbURI = "mongodb://localhost:27017/buddhafinds";
mongoose.connect(dbURI);
//Related functions and logs go here
require('./users');
I have been struggling with this since morning. Any help would be much appreciated. Thank you.
in your passport.js file you create a model without a schema
var User = mongoose.model('User');
try to assign the model to schema in your users.js file and export it from there
exports.User = mongoose.model('User', userSchema)
then just require User in any file you want
I have a background in PHP MVC and just started learning Nodejs.
This is my app directory structure:
root
- controllers
-user.js
- model
-user.js
- public
-stylesheet
-style.css
- views
-index.jade
- app.js
- package.json
- gulpfile.js
This is my controller file: user.js
var User = require('../models/user.js');
exports.list = function(req, res){
User.find(function(err, users) {
res.send(users);
});
};
This is my model file: user.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.createConnection('mongodb://localhost/mydb');
var userSchema = new Schema({
name: String,
country: String,
email: String,
password: String,
});
module.exports = mongoose.model('user', userSchema);
Below is my app.js file:
/**
* Module dependencies.
*/
var express = require('express')
, controllers = require('./controllers')
, employee = require('./controllers/employee')
, user = require('./controllers/user')
, http = require('http')
, path = require('path');
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', controllers.index);
app.get('/employees', employee.list);
app.get('/user',user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
I have created a database in mongo using the command line and below is my collections list:
I may still be thinking it the php way and missing some point here. Could someone point out what I am doing wrong here ?
Mongoose automatically looks for the plural version of your model name, more details about this rule please refer to the source code, Mongoose.model definition is
Mongoose#model(name, [schema], [collection], [skipInit])
To solve your issue, you could define your model
mongoose.model('user', userSchema, { collection: 'user' });
I made an express app, and it has an app inside of that called users. I am using Typescript. This is what my app.js file looks like:
///<reference path='d.ts/DefinitelyTyped/node/node.d.ts' />
///<reference path='d.ts/DefinitelyTyped/express/express.d.ts' />
///<reference path='routes/Users.ts' />
import express = require("express");
import http = require("http");
import path = require("path");
import us = require("./routes/Users");
var app = express();
// all environments
app.set('port', 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('env', 'development');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', (req, res) => {
res.render("index", {
title: "Express Main Page"
});
});
// Users app
app.use(us.Users.users);
http.createServer(app).listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'));
});
Right now, the problem is this, I am using mongoose to store some data, and I have mongodb started. Here is what the Users.ts file looks like:
/// <reference path='../d.ts/DefinitelyTyped/node/node.d.ts' />
/// <reference path='../d.ts/DefinitelyTyped/express/express.d.ts' />
/// <reference path='../d.ts/DefinitelyTyped/mongoose/mongoose.d.ts' />
import express = require("express");
import mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/SimpleBlog");
export module Users {
// Exporting information about the user class
export var users: Express = express();
export var base_URL: string = "/users";
// Making Schemas
var UserSchema = new mongoose.Schema({
email: String,
name: String,
age: Number
});
// Attaining users
var db_Users = mongoose.model('Users', UserSchema);
var list;
db_Users.find({}, (err, docs) => {
list = docs;
console.log(docs);
});
// Route for base url
users.get(base_URL, (req, res) => {
res.render("Users/index", {
title: "User List",
user_list: list
});
});
// Route for POST request
users.post(base_URL + "/add", (req, res) => {
try {
console.log(req.body['name']);
new UserSchema({
name: req.body['name'],
email: req.body['email'],
age: req.body['age']
}).save(function (err, docs) {
if (err) { console.log(err); }
});
} catch (Exception) {
console.log(Exception);
}
res.redirect(base_URL);
});
users.get(base_URL + "/add", (req, res) => {
res.render("Users/add", {});
});
}
I get [TypeError: object is not a function] as the error, when I try to save.
The users/add simple gives the user a registration form, and this is done in a jade file. I can also attest that it is not a problem with express.bodyParser() since console.log(req.body['name']); prints out the name of the post request correctly.
Any help regarding this would be helpful.
Your syntax isn't correct for Mongoose.
Regarding this line:
// Attaining users
var db_Users = mongoose.model('Users', UserSchema);
That line returns a Model function/constructor. You'll use that result to create instances of a User. Given all of the Users/UserSchema/User namespace you've got right now, it's a little confusing, so I'll switch it:
// Attaining users
var UserModel = mongoose.model('User', UserSchema);
It looks like the class represents a User, not Users.
When you want to create an instance of a User, you'd create an instance of the UserModel class rather than the schema:
new UserModel({
name: req.body['name'],
email: req.body['email'],
age: req.body['age']
}).save(function (err, docs) {
if (err) { console.log(err); }
});
I try to simply save a new User in my mongodb base into a controller file :
var mongoose = require('mongoose');
var UserModel = mongoose.model('User');
// signup
exports.create = function (req, res) {
console.log(req.body);
var user = new UserModel({
username: req.body.username,
password: req.body.password,
email: req.body.email
});
user.save(function (err) {
if (!err) {
return console.log("created");
}
else {
return console.log(err);
}
});
}
In debug mode, I can see that user.save() is not executed without error...
I don't know why because I get correct value in username / password / email field.
Here my model file :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var objectId = Schema.ObjectId;
var userSchema = mongoose.Schema({
username: String,
password: String,
email: String
});
var userModel = mongoose.model('User', userSchema);
EDIT :
In my app.js I have the connection to mongodb :
mongoose.connect('mongodb://localhost/mydb', function(err){
if(err) {
console.log(err);
}
});
var userModel = require('./models/user'),
userController = require('./controllers/users');
I grouped all (controller + model) in one file to test :
var express = require('express')
, routes = require('./routes')
, userRoute = require('./routes/user')
, http = require('http')
, path = require('path')
, io = require('socket.io')
, mongoose = require('mongoose');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
mongoose.connect('mongodb://127.0.0.1/mydb', function(err){
if(err) {
console.log(err);
}
else {
console.log("Connected to mongo DB")
}
});
/*var userModel = require('./models/user'),
tchatMessageModel = require('./models/tchatMessage'),
userController = require('./controllers/users'),
tchatMessageController = require('./controllers/tchatMessages'); */
app.get('/', routes.index);
app.get('/signup', userRoute.signup);
app.get('/signin', userRoute.signin);
//app.post('/signup', userController.create);
//app.get('/users', userRoute.list);
var Schema = mongoose.Schema;
var userSchema = Schema({
username: String,
password: String,
email: String
});
var UserModel = mongoose.model('User', userSchema);
app.post('/signup', function (req, res) {
console.log(req.body);
var user = new UserModel({
username: req.body.username,
password: req.body.password,
email: req.body.email
});
user.save(function (err) {
if (!err) {
return console.log("created");
}
else {
return console.log(err);
}
});
});
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
And I get the same issue... don't understand. Maybe issue in Express configuration ?
EDIT :
Issue solved with :
app.js
mongoose.model("User", require("./models/user").userModel);
model.js
exports.userModel = userSchema;
You should use keyword "new", when you are creating a mongoose Schema:
var userSchema = new mongoose.Schema({
/*...*/
});
I'm curious if anyone could provide some insight on the best way to abstract an API built with Node.js + Restify + Mongoose. After coming from an MVC / PHP background, it's interesting to find that there's not string/defined structure for Node applications.
As of now, I have my app.js file that auto loads my routes.js file, all model js files, etc.
The confusion is primarily in how my routes are supposed to interact with data from Mongo. Here is a basic rundown on how my code is layed out.
app.js:
/**
* Require Dependencies
*/
var restify = require('restify')
, mongoose = require('mongoose')
, config = require('./config')
, routes = require('./routes');
/**
* Create Server & Define Settings
*/
var server = restify.createServer({
name: config.name,
version: config.version
});
/**
* Common Handlers
*/
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(restify.jsonp());
/**
* Connect to Mongo Database
*/
mongoose.connect(config.mongo.uri, function(err) {
// assign connection to var so we can pass it down the chain
var db = mongoose.connection;
// handle connection error
db.on('error', console.error.bind(console, 'connection error:'));
// handle connection success
db.once('open', function callback () {
/**
* Start Routing API Calls
*/
routes.route(server, db);
});
});
/**
* Start Server & Bind to Port
*/
server.listen(config.port, function () {
console.log('%s v%s listening on port %s in %s mode.', server.name, server.version, config.port, config.env);
});
routes.js:
module.exports.route = function(server, db) {
var Users = require('./models/users.js');
/**
* Users
*/
server.get('/users', function (req, res, next) {
res.send(Users.list(db, req, res));
return next();
});
server.get('/users/:user_id', function (req, res, next) {
res.send(Users.get(db, req, res));
return next();
});
}
models/users.js:
// fake database
var users = [
{
name: 'Nick P',
email: 'nick#domain.com'
},
{
name: 'Zack S',
email: 'zack#domain.com'
}
];
exports.list = function(db, req, res) {
return users;
};
exports.get = function(db, req, res) {
return users[req.params.user_id];
};
As you can see, I'm using a "fake database" that is a simple object. Where / how could I introduce a Mongoose layer to communicate with our database? I'm mostly concerned with how I should use schemas and exports. Any code examples, or direction would be awesome.
Here a simple example of what I usually do with Express, it's kind of the same thing with Restify. You can manage your Mongoose schemas in the same way but in your Restify routes.
app.js :
var express = require('express');
var app = express();
app.configure(function () {
app.use(express.logger('dev'));
app.use(express.bodyParser());
});
// connection to mongoDB
var mongoose = require('mongoose');
mongoose.connect('mongodb:mongoURI');
var user = require('./routes/users');
app.get('/users/list', user.list);
app.listen(3000);
models/user.js :
var mongoose = require('mongoose')
,Schema = mongoose.Schema
,ObjectId = Schema.ObjectId;
var userSchema = new Schema({
id: ObjectId,
name: {type: String, default: ''},
email: {type: String, default: ''}
});
module.exports = mongoose.model('User', userSchema);
routes/users.js :
var User = require('../models/user.js');
exports.list = function(req, res) {
User.find(function(err, users) {
res.send(users);
});
};