model.find is not a function - javascript

I am trying to learn node.js with mongoose. Simply want to read from database and display result in a browser. I have index.js where I compiled model from schema as
var mlink = mongoose.model('mlink',mlinkSchema)
Then I exported it so as to use it in server.js file as
module.exports = mongoose.model('mlink',mlinkschema);
Under server.js, I require it as
const mlink = require(__dirname, "../Scripts/index.js");
And now, I am using express router as below
const express = require('express');
const app = express();
const router = express.Router();
app.use("/", router);
router.route("/Scripts").get(function(req,res){
mlink.find({},function(err, result){
if (err) {
res.send(err);
}
else {
res.send(result);
}
});
});
Here I keep on getting error as mlink.find is not a function. Please help I am stuck.

Instead of this
module.exports = mongoose.model('mlink',mlinkschema);
It should be
module.exports = mlink;

If you have a correct model than
module.exports = mongoose.model('mlink',mlinkSchema);
should work (you had a typo in mlinkSchema it needs to have a capital S)
You would import a model like this:
const mlink = mongoose.model("mlink");
Getting data from MongoDB is time consuming it should be an asynchronous function
router.route("/Scripts").get(async function(req,res){
await mlink.find({},function(err, result){
if (err) {
res.send(err);
}
else {
res.send(result);
}
});

Related

Trying to pass data from form to page but getting " " is not defined

I am trying to build a node app. I have my routes built properly and , all my dependencies installed properly but when trying to load the ("/) "homepage" I get "newPost" is not defined.The ("/new) page works fine, here is what my code looks like. I've also properly linked to the Schema route. Thank you in advance!
var express= require("express");
var app = express();
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var Post = require("./models/post");
app.set("view engine","ejs")
app.use(bodyParser.urlencoded({extended: true}));
mongoose.connect("mongodb://localhost/blog")
//=================================================
app.get("/",function(req,res){
Post.find({},function(err,foundPost){
if(err){
console.log(err)
}else{
res.render("homepage",{post:newPost}); <--- this is the problem
}
})
});
app.get("/new",function(req,res){
res.render("post/new")
});
app.post("/",function(req,res){
var title= req.body.title;
var image= req.body.image;
var description = req.body.description;
var fullPost ={title:title,image:image,description:description};
Post.create(fullPost,function(err,newPost){
if(err){
console.log(err)
}else{
res.redirect("/")
}
})
})
The exception is telling you exactly the issue
I get "newPost" is not defined
newPost doesn't exist here....
app.get("/",function(req,res){
Post.find({},function(err,foundPost){
if(err){
console.log(err)
}else{
res.render("homepage",{post:newPost});
}
})
});
Did you mean to use foundPost?

Export functions or variables to another module in node.js

I know there are lots of questions similar to mine but I could not find the best solution.
I am creating a web app with node and rethinkdb. I want to organise different js files (modules) so that each has specific task.
I have this query.js file whose query result must be passed to routes.js file.
I have tried implement this in the following way.
query.js
//dependencies
var express = require('express');
var path = require('path');
var r = require('rethinkdbdash')({
port: 28015,
host: 'localhost',
db: 'stocks'
});
var len;
//function to get companies list
exports.clist = function(){
r.table('company')
.run()
.then(function(response){
return response;
})
.error(function(err){
console.log(err);
})
}
console.log(exports.clist[0].id)
//function to get number of entries in database
exports.clen = function(){
r.table('company')
.run()
.then(function(response){
len = Object.keys(clist).length;
return len;
})
.error(function(err){
console.log(err);
})
}
routes.js
//dependencies
var express = require('express');
var request = require('request');
var path = require('path');
var r = require('rethinkdbdash')({
port: 28015,
host: 'localhost',
db: 'stocks'
});
//query module
var query = require('./query')
clist = query.clist();
clen = query.clen();
//create router object
var router = express.Router();
//export router
module.exports = router;
//home page
router.get('/', function(req, res) {
console.log('served homepage');
res.render('pages/home');
});
//--companies page--//
router.get('/company', function(req,res){
console.log('served companies page')
res.render('pages/company', {
clist: clist,
x:clen
});
});
the console log in query.js is showing that cannot read property id of undefined.
Also I would like to know is there a way to directly pass the variables instead of using functions and then calling it.
I apologise if the solution is obvious.
To summarise I want the query result which is an object to be accessible from routes.js file.
Note: As exports.clist1 is an asynchronous method, you can't expect the result to be printed in the next line, hence comment this line and follow as below
//console.log(exports.clist[0].id)
You have to register a middleware to make this working, otherwise, query will be called only at the time of express server started and not at every request.
So you can do like this,
Hope you had something like this in your startup file (app.js),
var app = module.exports = express();
routes.js
//query module
var query = require('./query')
var app = require('../app'); // this should resolve to your app.js file said above
//clist = query.clist();
//clen = query.clen();
// middleware to populate clist & clen
app.use(function(req, res, next){
query.companyList(function(err, data){
if(!err) {
req.clist = data.clist;
req.clen= data.clen;
}
next();
});
});
query.companyList(function(err, data){
if(err) {
console.log(err);
} else {
console.log(data.clist[0].id);
console.dir(data.clist);
}
});
//create router object
var router = express.Router();
//export router
module.exports = router;
//home page
router.get('/', function(req, res) {
console.log('served homepage');
res.render('pages/home');
});
//--companies page--//
router.get('/company', function(req,res){
console.log('served companies page')
res.render('pages/company', {
clist: req.clist,
x: req.clen
});
});
Change your query.js like this,
//function to get companies list
exports.companyList = function(next){
r.table('company')
.run()
.then(function(response){
var list = {
clist: response,
clen: Object.keys(response).length
};
next(null, list);
})
.error(function(err){
console.log(err);
next(err);
})
};

Express app use after DB callback

I'm using mysql-orm in a Nodejs Express app this is my code:
app.js:
// ... all variables are initialized
var orm = null;
var app = express();
db.create(dbSchema, dbSeeds, dbOptions, function(err, ormObject) {
if (err) throw err;
orm = ormObject;
});
var coursesRoutes = require('./routes/dashboard/courses')(orm);
app.use('/dashboard/courses', coursesRoutes);
/routes/dashboard/courses.js:
var express = require('express');
var router = express.Router();
module.exports = function(orm) {
router.get('/listall', function(req, res, next) {
orm.loadMany('sections', null, function(err, sections) {
if (err) throw err;
res.jsonp(sections);
});
});
return router;
};
And this returns this error:
TypeError: Cannot read property 'loadMany' of null
I know that the problem is that orm variable is passed to file before it is initialized in the db.create callback but I don't know how to solve this.
I tried to put:
var coursesRoutes = require('./routes/dashboard/courses')(orm);
app.use('/dashboard/courses', coursesRoutes);
inside the callback but it returns 404 not found
Your courses function is getting called before db connection is established.
This should do the trick.
var orm = null;
var app = express();
db.create(dbSchema, dbSeeds, dbOptions, function(err, ormObject) {
if (err) throw err;
orm = ormObject;
var coursesRoutes = require('./routes/dashboard/courses')(orm);
app.use('/dashboard/courses', coursesRoutes);
});

ExpressJs - dbQuery is not defined

In console, when I go to specific item id I have error(ExpressJs):
ReferenceError: dbQuery is not defined
My api.js
var express = require('express'),
Bourne = require('bourne'),
bodyParser = require('body-parser'),
db = new Bourne('data.json'),
router = express.Router();
....
.route('/contact/:id')
.get(function (req, res) {
db.findOne(req,dbQuery, function (err, data) { //problem
res.json(data);
});
})
....
module.exports = router;
dbQuery is not defined? If its coming from a form it needs to be req.body.dbQuery or req.query.dbQuery.
If set somewhere else, req.dbQuery needs to be a dot not a comma.

externalizing route.param() calls in Express.js

I want to extract some repetitive code into a single module in Node.js and Express.js
Together.js
var express = require('express');
var boom = require('express-boom');
var app = express();
var app.use(boom());
app.param('user', function(request, reply, next, id){
request.db.users.get(id, function(err, userInfo){
if (err) reply.boom.badImplementation(err);
else if (!userInfo || !userInfo.length) reply.boom.notFound();
else {
request.user = userInfo[0];
next();
}
})
})
app.get('/api/users/:user', function(request, reply){
reply.json(request.user);
});
app.listen(3000);
I have multiple routes I want to use this param conversion including: /users/:user, /api/users/:user, /checkout/:user/:barcode, etc. but each of the root routes (i.e. users, api, checkout) are in their own file and I am attaching them with app.use('/users', userRoutes);. As it is, I will have to put my user param conversion into EACH of these sub-route modules.
I would like to have an interceptors.js where I make all of the common param interceptor functions and only write them once. Here is an example of how I thought it would work.
app.js
var express = require('express');
var app = express();
app.use(require('./routes/interceptors'))
app.use('/users', require('./routes/users'));
app.use('/api', require('./routes/api'));
app.use('/checkouts', require('./routes/checkouts'));
app.listen(3000);
./routes/api.js
var express = require('express');
var api = express.Router();
api.get('/users/:user', function(request, reply){
reply.json(request.user);
});
module.exports = api;
./routes/interceptors.js
var express = require('express');
var boom = require('express-boom');
var interceptors = express.Router();
var interceptors.use(boom());
interceptors.param('user', function(request, reply, next, id){
request.db.users.get(id, function(err, userInfo){
if (err) reply.boom.badImplementation(err);
else if (!userInfo || !userInfo.length) reply.boom.notFound();
else {
request.user = userInfo[0];
next();
}
})
})
module.exports = interceptors;
There would of course be another file for each of checkout.js and users.js and they will be the same principal as api.js
When I do the above, the param interceptor is never run. No errors are throw that I can see.
Thank you all for any help you may provide,
Rhett Lowe
This can't be done.
Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on app will be trigerred only by route parameters defined on app routes.
http://expressjs.com/api.html#app.param
Another approach you could do is to have a module with your interceptors and require it in your route files where necessary.
./routes/api.js
var express = require('express');
var api = express.Router();
var interceptors = require('./interceptors');
api.use('user', interceptors.user);
api.get('/users/:user', function(request, reply){
reply.json(request.user);
});
module.exports = api;
./routes/interceptors.js
exports.user = function(request, reply, next, id){
request.db.users.get(id, function(err, userInfo){
if (err) reply.boom.badImplementation(err);
else if (!userInfo || !userInfo.length) reply.boom.notFound();
else {
request.user = userInfo[0];
next();
}
})
})
module.exports = interceptors;

Categories