How to translate outside router, request using i18n + express? - node.js

Currently I have integrated successfully to routes, request and config.
Application Structure
app.js - The entry point to our application. This file defines our express server and connects it to MongoDB using mongoose. It also requires the routes and models we'll be using in the application.
config/ - This folder contains configuration for passport as well as a central location for configuration/environment variables.
routes/ - This folder contains the route definitions for our API.
models/ - This folder contains the schema definitions for our Mongoose models.
routes/api/users.js
var mongoose = require('mongoose');
var router = require('express').Router();
var passport = require('passport');
var User = mongoose.model('User');
var auth = require('../auth');
router.post('/users', function(req, res, next){
var user = new User();
user.username = req.body.user.username;
user.email = req.body.user.email;
user.setPassword(req.body.user.password);
user.save(req, res).then(function(){
return res.json({user: user.toAuthJSON()});
}).catch(next);
});
module.exports = router;
models/User.js
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');
var crypto = require('crypto');
var jwt = require('jsonwebtoken');
var secret = require('../config').secret;
var UserSchema = new mongoose.Schema({
username: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true},
email: {type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/\S+#\S+\.\S+/, 'is invalid'], index: true},
bio: String,
image: String,
favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Article' }],
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
hash: String,
salt: String
}, {timestamps: true});
/**<<HERE>> Does not work inside the models. <<HERE>>**/
UserSchema.plugin(uniqueValidator, {message: i18n.__('user.register.errors.is_already_taken')});
mongoose.model('User', UserSchema);
app.js
var http = require('http'),
path = require('path'),
methods = require('methods'),
express = require('express'),
bodyParser = require('body-parser'),
session = require('express-session'),
cors = require('cors'),
passport = require('passport'),
errorhandler = require('errorhandler'),
mongoose = require('mongoose');
cookieParser = require('cookie-parser');
i18n = require('i18n');
var isProduction = process.env.NODE_ENV === 'production';
// Create global app object
var app = express();
app.use(cors());
app.use(cookieParser())
// Configure i18n
i18n.configure({
locales:['en', 'es'],
directory: __dirname + '/locales',
objectNotation: true,
//defaultLocale: 'en',
register: global,
cookie: 'lang'
})
i18n.init();
// you will need to use cookieParser to expose cookies to req.cookies
app.use(cookieParser());
// i18n init parses req for language headers, cookies, etc.
app.use(i18n.init);
// Support "Accept-Language" : "es" or "en" via headers
app.use(function (req, res, next) {
i18n.init(req, res);
if (typeof req.locale !== 'undefined') {
console.log('locale : ', req.locale);
i18n.setLocale(req.locale);
}else{
var locale = i18n.getLocale();
res.set('Content-Language', locale);
}
next();
});
// finally, let's start our server...
var server = app.listen( process.env.PORT || 3000, function(){
console.log('Listening on port ' + server.address().port);
});
But when I try translate inside a models/ for example i18n.__('my-key'), this does not detect the locale so this returns the locale for default "en", but from header i receive correctly the lang "es".
Please let me know how I will fix it :)

Related

Getting buffer timeout error when making a POST request to the database

I am getting a timeout error when I try to make a POST request to the database:
MongooseError: Operation `sessions.insertOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (/Users/don-alexantoine/Desktop/BCC-Website/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:185:20)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
This all started when I placed the routes into a different file. I don't what this why this is happening. I created API endpoints in the same manner and they work. Any help will be appreciated. Thanks in advance.
Here is the code:
Router.js file
const express = require('express');
const Session = require('../models/sessions')
const router = new express.Router();
router.get('/', (req, res)=>{
res.render('home');
});
router.post('/',async (req, res)=>{
try{
const session = new Session({
session_name: req.body.session_name,
first_name: req.body.fname,
last_name: req.body.lname,
room: req.body.room,
max_capacity: req.body.max,
session_time: req.body.time
});
console.log(session)
const newsession = await session.save();
console.log(newsession)
res.redirect('/')
}catch(e)
{
console.log(e)
}
})
module.exports = router
Sessions.js file
const mongoose = require('mongoose');
const SessionSchema = new mongoose.Schema({
session_name:{
type: String,
required:[true, 'session name is required'],
trim: true
},
first_name:{
type: String,
required:[true, 'Speaker last name is required']
},
last_name:{
type: String,
required: [true, 'Speaker last name is required']
},
room:{
required: [true, 'Room name is required'],
type: String
},
max_capacity: {
required: [true, 'Room max capacity is required'],
type: Number,
},
session_time: {
required: [true, 'Session time is required'],
type: String
},
room_counts:[{
count:{
type: Number,
},
time:{
type: String
}
}]
});
const Session = mongoose.model('session', SessionSchema);
module.exports = Session;
Main app file (app.js)
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const hbs = require('hbs');
const bodyparser = require('body-parser');
const sessionRouter = require('./routers/session');
const app = express();
const viewPath = path.join(__dirname, '../views');
const partialsPath = path.join(__dirname, '../views/partials');
app.use(bodyparser.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, '../public')));
app.use(sessionRouter);
app.set('views', viewPath);
app.set('view engine', 'hbs');
hbs.registerPartials(partialsPath);
app.listen(3000 || process.env.PORT, ()=>{
console.log('server is listening on port 3000');
});
Mongoose.js file
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/bccDB', {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify:true});
After, looking into your code below are the mistakes that I have found out
const sessionRouter = require('./routers/session'); your need to change this to const sessionRouter = require('./routers/Router');
secondly, your app is not connected to MongoDB. you have created the file but you have never called that file. I would recommend you to make a connect function, export it and call it inside the app.js
Mongoose.js
const mongoose = require('mongoose');
function connectDB() {
mongoose.connect('mongodb://localhost:27017/bccDB', {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify:true});
}
module.exports = {
connectDB
}
and initializing it inside app.js
const { connectDB } = require('./mongoose')
// create a connection to mongodb
connectDB()
Also, you need to handle the initialization in a better way in order to avoid crashing your application because of DB errors.

Why am I getting [] in the json response in postman always?

// controllers/users.js
'use strict';
var mongoose = require('mongoose'),
User = mongoose.model('Users');
exports.list_all_users = function(req, res) {
User.find({}, function(err, users) {
if (err)
res.send(err);
res.json(users);
});
};
// exports.list_all_users = function(req, res){
// res.send("display all users");
// };
exports.create_a_user = function(req, res){
res.send("user_created");
};
exports.delete_a_user = function(req, res){
res.send("user_deleted");
};
./routes/users.js
'use strict';
module.exports = function(app) {
var users = require('../controllers/users');
// users Routes
app.route('/users')
.get(users.list_all_users);
}
model/UserModel.js
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
_id:{
type : Number,
auto : true },
name: {
type : String,
required: 'Kindly enter the name '
},
password: {
type: String
},
email:{
type: String,
required: 'Kindly enter the mailId '
},
role:{
type: String,
required : 'Enter a valid role '
},
invitedBy: {
type: Number,
required : 'Valid number'
}
});
module.exports = mongoose.model('Users', UserSchema);
server.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
User = require('./model/UserModel'), //created model loading here
bodyParser = require('body-parser');
// mongoose instance connection url connection
var dbConfig = require('./db');
mongoose.Promise = global.Promise;
mongoose.connect(dbConfig.config);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var userRoutes = require('./routes/users'); //importing route
userRoutes(app); //register the route
app.listen(port);
console.log('todo list RESTful API server started on: ' + port);
I tried printing 'display as respone' to response and it works, the database connection is successful.
But when I try to get from the db, it prints[] for /users get
I suspect something is wrong with my model
Can anyone point out what went wrong here ?
My collection:
collection : "Users"
{
"_id": 112,
"name": "abcd",
"password": "hash12341234",
"email": "questioner#hotmail.com",
"role": "musician",
"invitedBy": 1
}
In you controllers/user.js, you have tried to created a user model again. Can you try importing as follows,
var mongoose = require('mongoose'),
User = require('../model/UserModel')
In you userModel.js, you need to also place a connection string
var db = mongoose.connect("mongodb://localhost/XXXXX");
var Schema = mongoose.Schema;
You just need to replace a line in controller/user.js
Use:
User = require('../model/UserModel')
instead of:
User = mongoose.model('Users');
Hope this helps.
Actually, the issue is that, the get function is returning the objects in collection created only using the model in Node.
I tried creating the user with the api and tested get users but it works like charm.
I am still puzzled about why it is unable to return the objects from the collection which were created by me manually.

Unhandled promise Rejection (rejection id: 1) - Node.js

I'm new to Node.js and trying to figure out of some problems.
I've defined a signup function on a Node.js server for an Android app who writes user's info on MongoDB.
server.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
Task = require('./api/models/serverModel'),
bodyParser = require('body-parser');
var url = "mongodb://localhost:27017/ProjectDB";
mongoose.Promise = global.Promise;
mongoose.connect(url);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./api/routes/serverRoute');
routes(app);
app.listen(port);
console.log('Project RESTful API server started on: ' + port);
serverModel
var UserSchema = new mongoose.Schema({
userName: {type: String, unique: true, required: true},
email: {type: String, unique: true, required: true},
password: {type: String, required: true},
createdAt: {type: String, required: true}
});
var User = mongoose.model('User', UserSchema);
module.exports = User;
serverRoute
module.exports = function(app) {
var Project = require('../controllers/serverController');
// Project Routes
app.route('/signup')
.post(Project.signup);
};
serverController
...
mongoose.Promise = global.Promise;
exports.signup = function(req, res) {
return new Promise( function(resolve,reject) {
var user = new User({
userName: req.body.name,
password: req.body.pass,
mail: req.body.email,
createdAt : new Date()
});
user.save()
.then(function() { resolve({ status: 201, message: 'User Registered Successfully !' })})
.catch(function(err) {
if (err.code == 11000) {
reject({ status: 409, message: 'User Already Registered !' });
} else {
reject({ status: 500, message: 'Internal Server Error !' });
}
});
})};
...
It compiles without any error.
When I try to send a JSON via Postman like this:
{
"userName" : "username",
"email" : "user.name#gmail.com",
"password" : "blabla1"
}
it reports
UnhandledPromiseRejectionWarning: Unhandled promise Rejection (rejection id: 1) [object Object]
I've read tons of posts but I can't get out of this.
Any help?
Thanks.
Try this and revert.
server.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
mongoose = require('mongoose'),
Task = require('./api/models/serverModel'),
bodyParser = require('body-parser');
var url = "mongodb://localhost:27017/ProjectDB";
mongoose.Promise = global.Promise;
mongoose.connect(url);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./api/routes/serverRoute');
//change
//routes(app);
app.use('/',routes);
app.listen(port);
console.log('Project RESTful API server started on: ' + port);
serverRoute
var express = require('express');
var router = express.Router();
// GET home page.
router.post('/signup', function(req, res, next) {
var Project = require('../controllers/serverController');
Project.signup().then(function(result){
res.send(result);
}).catch(function(err){
res.send(err);
});
});
module.exports = router;

Mongoose doesn't insert in MongoLab

I'm trying to build my first MEAN Stack application and I'm using postman to check my insertion in my DB and I get a message that says "user created!", but after checking the DB in MongoLab. I do not get any document inserted in the collections. here's my code:
Here's my repo in case you need it: https://github.com/pevargasg/joberistyNode
app.js
var express = require('express')
var app = express()
var morgan = require('morgan');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
//My one modules
var User = require('./app/models/user');
var Company = require('./app/models/company');
//Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(morgan('dev'));
//Connection to DB
//mongoose.Promise = global.Promise;
//Feel free to use your own mongoLab link below for testing purposes
mongoose.connect('mongodb://user:password#dsXXXXXX.mlab.com:19768/jobersity',function(err){
if(err){
console.log("Not connection to DB" + err);
throw err;
}
else{
console.log("Connected to DB");
}
});
//Routes
/*app.get('/', function (req, res) {
res.send('Hello World!')
})*/
//Creating Users
app.post('/users',function(req,res){
//res.send('test');
var user = new User();
user.username = req.body.username;
user.password = req.body.password;
user.email = req.body.email;
/*user.firstName = req.body.firstName;
user.lastName = req.body.lastName;
user.major = req.body.major;*/
//Save user
user.save();
res.send('user created!');
});
user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//Table for usersSchema
var UserSchema = new Schema({
username:{type: String, lowercase: true, required: true, unique: true},
password:{type: String, required: true},
email:{type: String, lowercase: true, required: true, unique: true},
/*firstName: {type: String, required: true},
lastName: {type: String, required: true},
major: {type: String, required: true},
jobsApplied:[{
title: String,
description: String,
position: String
}]*/
});
module.exports = mongoose.model('User', UserSchema);
Your code works successfully when I run it.
Two things I did notice:
Your package.json file includes mongojs when it doesn't seem to get used. The mongooose package will pull the mongodb dependency it need when you call npm install.
Your connection string is included in clear text in your repository. Try to get in the habit of importing any sensitive information into your app through a config file.
For example, create a config file, e.g. ./config/db.js:
module.exports = {
'uri' : 'mongodb://user:pwd#host1:port1/dbname'
}
Then import the file into your app:
var dbConfig = require('./config/db.js');
The variable can then be used be used in your code:
mongoose.connect( dbConfig.uri, function(err){ ... } )
Finally, add this file (./config/db.js) to your .gitignore.

Mongoose and node js - TypeError: object is not a function

The issue that it doesnt let me use the genre schema
i have 2 schemas user and genre
user schema works fine but the genre schema is undefind
user.js - schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Genre = require('../Models/genre');
// create a schema
var userSchema = new Schema({
name: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
age: String,
gender: String,
genres: [Genre.genreSchema]
});
// the schema is useless so far
// we need to create a model using it
var User = mongoose.model('User', userSchema);
// make this available to our users in our Node applications
module.exports = User;
genre.js - schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a schema
var genreSchema = new Schema({
name: { type: String, required: true, unique: true },
age: String,
gender: String
});
// the schema is useless so far
// we need to create a model using it
var Genre = mongoose.model('Genre', genreSchema);
// make this available to our genres in our Node applications
module.exports = Genre;
genre controller - router --- same as user router controller
var express = require('express');
var bodyParser = require('body-parser');
var Genre = require('../Models/genre');
// ROUTES FOR OUR API
// =============================================================================
var router = express.Router(); // get an instance of the express Router
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
next(); // make sure we go to the next routes and don't stop here
});
router.route('/genres')
// create a genre
.post(function(req, res) {
console.log(Genre);
**//here is the error when trying to post new genre**
var Genre = new Genre(req.body); // create a new instance of the user model
// save the genre and check for errors
Genre.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Genre created!' });
});
})
// get all the genres
.get(function(req, res) {
Genre.find(function(err, genres) {
if (err)
res.send(err);
res.json(genres);
});
});
module.exports = router;
server.js - the app js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var userRouter = require('./Controllers/user');
var genreRouter = require('./Controllers/genre');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017'); // connect to our datababase
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set our port
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', userRouter);
app.use('/api', genreRouter);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('see whats happening on port ' + port);
why the model is undefind only when i post new genre? and for user it works fine?
is it the way to do schema whithin schema? or there is a better way?
i have try to use only the genre model with out the user and it still same error
i hope i am clear enough
thanks for the helpers
You shouldn't be using the same name for the schema and for the new Genre.
try changing it to
var newGenre = new Genre(req.body); // create a new instance of the user model
// save the genre and check for errors
newGre.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Genre created!' });
});

Resources