I'm trying to send some data to a database using mongoose. Here is my code so far.
server.js
var express = require('express');
var wine = require('./routes/wines');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.get('/wines', wine.findAll);
app.get('/wines/:id', wine.findById);
app.listen(3000);
console.log('Listening on port 3000...');
wine.js (inside models folder)
var mongoose = require('mongoose');
var db = mongoose.connection;
var wineSchema = new mongoose.Schema({
name: String,
description: String
});
var Wine = mongoose.model('Wine', wineSchema);
module.exports = Wine;
wines.js (inside routes folder)
exports.addWine = function(req, res) {
// Problem not defined here
var silence = new Wine({ name: 'Silence', description:"cena" })
console.log(silence.name) // 'Silence'
// add it to the database
};
I keep getting this error and i have no idea why.
ReferenceError: Wine is not defined
I've exported Wine in wine.js (models), shouldn't I be able to use it everywhere ?
Thank you in advance !
Add var Wine = require('./../models/wine.js'); at the beginning of wines.js (assuming your routes and models folders are contained within the same directory).
Exporting objects/values/functions from node modules does not make them globally available in other modules. The exported objects/values/functions are returned from require (reference here for more info). That said, Mongoose uses an internal global cache for models and schemas which make it available via mongoose (or a connection) throughout an app.
So in your routes file you could do something like:
var Wine = mongoose.model('Wine'); // Notice we don't specify a schema
exports.addWine = function(req, res) {
var silence = new Wine({ name: 'Silence', description:"cena" })
console.log(silence.name) // 'Silence'
// add it to the database
};
Related
Creating a small web app on the MEAN stack and I'm in the process of migrating my schemas to a separate "models" directory. When the schemas are defined in the same app.js file, everything works fine; however, when I switch the code to a separate more modular file and import it I get this error:
TypeError: Player.find is not a function
at /Users/username/code/express/WebApp/v3/app.js:57:12
This error occurs when it gets to that first route where it needs to look players up and I'm not quite sure what I'm missing after staring at this for hours.
My app.js file:
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
Player = require("./models/players")
const port = 3000;
mongoose.connect("mongodb://localhost/players", { useNewUrlParser: true, useUnifiedTopology: true });
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended: true}));
// PLAYER SCHEMA ORIGNALLY DEFINED HERE BUT NOW ATTEMPTING TO MOVE TO DIFF DIRECTORY & IMPORT
/*var playerSchema = new mongoose.Schema({
player: String,
position: String,
description: String
});
var Player = mongoose.model("Player", playerSchema);*/
app.get("/", function(req, res) {
res.render("landing");
});
app.get("/players", function(req, res) {
// Get all players from DB
Player.find({}, function(err, allPlayers){
if(err){
console.log(err);
} else {
console.log("We're good.");
res.render("players", {players: allPlayers});
}
});
});
and my player.js file that I'm attempting to import:
var mongoose = require("mongoose");
var playerSchema = new mongoose.Schema({
player: String,
position: String,
description: String
});
// Compile into a model
module.exports = mongoose.model("Player", playerSchema);
The above schema definition and model definition work completely fine when they're in the app.js file, but not when imported. What am I missing here? Thanks in advance for the help.
I think your file name is wrong at the require statement. Its
const Player = require('../models/player')
as your file name is player.js, not players.js and if you stored the js file in a model folder. Do check out how to navigate using the file path
/ means go back to the root folder, then traverse forward/downward.
./ means begin in the folder we are currently in and traverse forward/downward
../ means go up one directory, then begin the traverse.
And also your backend should look like this.
Backend File Management
I am trying to add a method
loadSiteSettings to express module
In app.js
var express = require('express');
var path = require('path');
var mongoose = require('mongoose');
//Set up default monggose connection for mongo db
var mongoDB = 'mongodb+srv://***:*****#cluste******j.mongodb.net/cms?retryWrites=true&w=majority';
mongoose.connect(mongoDB,{useNewUrlParser: true});
//Get the default connection
var db = mongoose.connection;
//Bind connection to error event (to get notification of connection errors)
db.on('error',console.error.bind(console, 'MongoDB connection error:'));///????????
var app = express();
///////////////////////////////////////////////////////////
var indexRouter = require('./routes/index');
app.loadSiteSettings = async function()
{
let setting = await db.collection('settings').findOne();
app.locals.siteSettings = setting;
}
app.loadSiteSettings();
//////////////////////////////////////////////////////
module.exports = app;
Index.Js for router
var express = require('express');
var router = express.Router();
var app = require('../app');
var util = require('util');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
///////////////////////////////////////////
router.get('/reloadSettings', function(req,res,next){
app.loadSiteSettings();
})
///////////////////////////////////////
module.exports = router;
so problem lies here, when server start it calls app.loadSiteSettings() in app.js
but when i use route '/reloadSettings' it seems app is undefined in index.js
This is an issue with circular dependencies and module.exports. This answer shows the same problem.
What's happening is app.js is required first and starts processing. The important thing to understand is that a file pauses execution while requiring a new file.
So when app.js requires ./routes/index, it has not finished processing, and has not reached module.exports = app. This means that when your routes file requires app.js, it's requiring it in its current state, which is the default export {}.
Thankfully there's a very simple fix:
// can be imported and tested separately from the app
const loadSiteSettings = function() {
return db.collection('settings').findOne();
}
router.get('/reloadSettings', async function(req,res,next){
let settings = await loadSiteSettings();
req.app.locals.siteSettings = settings
res.send(200); // signal the response is successful
})
This explains the issue in a lot more depth in case you're interested
I have structured a user collection using mongoose.model().This model exist in seperate file called as model\user.js. The mongodb connection instance (using mongoose) exist in seperate file db\mongoose.js. Both of these files are imported into server.js to work with web application.
var express = require('express');
var bodyParser = require('body-parser');
var {mongoose} = require('./db/mongoose');
var {User} = require('./models/user');
var app = express();
app.use(bodyParser.json());
app.post('/todos', (req, res) => {
var user = new User({
text: req.body.text
});
user.save().then((doc) => {
res.send(doc);
}, (e) => {
res.status(400).send(e);
});
});
app.listen(3000, () => {
console.log('Started on port 3000');
});
module.exports = {app};
The {mongoose} and {User} seems to be a separate entities and model\user.js didn't import ./db/mongoose.js as well . The user model being static content , how does user.save() connects with db and save the document?
First of all let me tell you what is happening in your project.
in Mongoose file:
You have DB connection with Mongoose.
Now Mongoose has your DB connection.
That is the reason it is imported in server.js file.
Secondly, in you model/user.js you have
Declared Schema using Mongoose.
user.save method.
When you use Mongoose here (or any DB related query), it points to your connected DB. Which does not require any explicit connection written in some file.
For more details read Mongoose Docs.
Hope I cleared your thoughts.
I am trying to run a simple node application using nide modules and testing it using the Advance Rest Client.
The console is not showing any error.
But I am not getting anything in the output.
While running this on ARC, I am getting : Cannot /GET data
Text version of the code:
MainFile:
var express = require('express');
//var morgan = require('morgan');
var bodyparser = require('body-parser');
var hostname = 'localhost';
var port = '3000';
var app = express();
//app.use(morgan('dev'));
var dishRouter = express.Router();
dishRouter.use(bodyparser.json());
var allDishes = require('./dishRouter');
//For all dishes
dishRouter.route('/dishes')
.get(allDishes.dishesGet)
.delete(allDishes.dishesDelete)
.post(allDishes.dishesPost)
;
//For specific dishesDelete
dishRouter.route('/dishes/:dishid')
.get(allDishes.dishSpecificGet)
.delete(allDishes.dishSpecificDelete)
.put(allDishes.dishSpecificPut)
;
app.listen(port,hostname,function(){
console.log('server runing properly');
});
dishRouter file:
console.log('in dishrouter file');
module.exports.dishesGet = function(req,res,next){
console.log('inside GET');
res.end('Will be displaying all the dishes');
};
module.exports.dishesDelete = function(req,res,next){
res.end('Will delete all the dishes');
};
module.exports.dishesPost = function(req,res,next){
res.end('will add the new dishes');
};
module.exports.dishSpecificGet = function(req,res,next){
res.end('displaying the specific dish :'+req.params.dishid);
};
module.exports.dishSpecificDelete = function(req,res,next){
res.end('Will delete the specific dish with id : '+req.params.dishid);
};
module.exports.dishSpecificPut = function(req,res,next){
res.write('will update the specific dish :'+req.params.dishid);
res.end('Updating the dish with values as name : '+req.body.name);
};
According to body-parser docs
Looks like your router is a bit broken here:
dishRouter.use(bodyParser.json())
Try switching this to:
app.use(bodyParser.json())
And I can recommend creating router in the file, where you write handlers and just export router.
UPDATE:
Here is what you forgot:
app.use(dishRouter)
When calling express.Router() you're just creating an instance of the router, but you have to connect it to the express application instance.
I'm learning the MEAN stack and have found myself with a load order issue that doesn't seem to make sense.
The below code shows my server.js loading the routes file, which in turn pulls in the controller for a model, which in turn requires the model itself.
If I don't include a reference to the model from routes.js I get a MissingSchemeError when I startup the server. Why? Am I missing something regarding the loading of resources?
My understanding was that the exports for a file would be completely imported by the require() prior to attempting to run any code.
server.js
// modules =================================================
var express = require('express');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
var morgan = require('morgan');
var app = express();
// configuration ===========================================
// config files
var db = require('./config/db');
// set our port
var port = process.env.PORT || 8080;
// connect to our mongoDB database
mongoose.connect(db.url);
// get all data/stuff of the body (POST) parameters
// parse application/json
app.use(bodyParser.json());
// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(methodOverride('X-HTTP-Method-Override'));
// set the static files location /public/img will be /img for users
app.use(express.static(__dirname + '/public'));
// set morgan to log requests
app.use(morgan('dev'));
// routes ==================================================
require('./app/routes')(app);
routes.js
//this line is the problem. why is this needed?
var Customer = require('./models/customer'); // <--
var customers = require('./controllers/customer-server-controller');
module.exports = function(app) {
app.route('/api/customers')
.get(customers.list);
//.post(customer.create);
}
customer-server-controller.js
var mongoose = require('mongoose');
var Customer = mongoose.model('Customer');
/**
* List of Customers
*/
exports.list = function(req, res) {
Customer.find().sort('-created').exec(function(err, customers) {
if (err) {
return res.status(400).send({
message: "ERROR: " + err
});
} else {
res.jsonp(customers);
}
});
};
Got a good portion of the biolerplate from this tutorial on Scotch.io
I take it that you're missing the model from the tutorial
You should have this somewhere.
Create a models folder and add todo.js and add the following:
// define model =================
var Todo = mongoose.model('Todo', {
text : String
});
Your customer-server-controller.js doesn't require() the model file, it just tries to reference the model by asking Mongoose for it (Mongoose doesn't load the model file for you!):
var Customer = mongoose.model('Customer');
You need to require() the module file from your controller, otherwise the model isn't registered with Mongoose and you get the error that you got.