Express making mongodb data available in route - node.js

This seems like a relatively simple issue, but I can't seem to find good documentation. I'd like to pass json data from mongodb into a route, so that it is available in my ejs template.
My schema is:
var GiveSchema = new Schema({
title: String,
shortname: String,
contents: String,
image: String,
category: String
});
module.exports = mongoose.model('GiveData', GiveSchema);
var Givedata = mongoose.model( 'GiveData' );
I'd like to pass make it available to my route below, as the variable list:
app.get('/', function(req, res) {
res.render('index.ejs',{
list: Givedata,
bootstrappedUser: req.user,
page: 'home'
});
});

You'll still need to query the database for your items.
app.get('/', function(req, res, next) {
Givedata.find(function(err, items){
if(err) { return next(err); }
res.render('index.ejs',{
list: items,
bootstrappedUser: req.user,
page: 'home'
});
});
});

Related

Issue with fetching value from mongodb using mongoose it always returns [ ]

I'm trying to learn mongoose with nodejs and created a following node function as below where in I'm receiving the email ID from the Angular application and based on the EmailId trying to find the records in MongoDb:
const express = require('express');
const mongoose = require('mongoose');
var bodyParser= require("body-parser");
const port = 3000;
const app = express();
//setting up bodyParser middleWare
app.use(bodyParser.urlencoded({"extended":true}))
app.use(bodyParser.json());
//setting mongoose connection to local mongoDb
mongoose.connect("mongodb://127.0.0.1/userDetails",{useNewUrlParser:true,useUnifiedTopology:true})
const db = mongoose.connection;
var userSchema = new mongoose.Schema({
email:{type:String},
userId:{ type: String, required: true },
password:{ type: String, required: true }
});
var users = mongoose.model('User', userSchema);
//error handler middleWare
app.use(function(err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
});
app.post("/login",async(req,res,next)=>{
try {
await users.find({ email:"xyz#gmail.com"}).exec(function (err, docs) {
if (err){
console.log(err);
}
else{
console.log("First function call : ", docs);
}
})
}
catch(err){
next(err);
}
})
app.listen(port,()=>{console.log("server started")});
The above code shows no error, but the output is always First function call : [].My mongodb collection is as follows
db.User.insertMany([
{ email: "xyz#gmail.com", userId:1,password : "123#124" },
{ email: "abc#yahoo.com",userId:2,password : "123#125"},
{ email: "lmn#outlook.com", userId:3,password : "123#126"}
])
db.User.find({ email: "xyz#gmail.com"});
Where is that I'm going wrong ,what should be the approach to get the data?
Your code should find and print the data to the console assuming the email address you're looking for is actually in the collection. However, I want to point out a few things that don't quite make sense.
There is absolutely no reason to await the function call await users.find({ email:"xyz#gmail.com"}).... So you should change it to users.find({ email:"xyz#gmail.com"})
With that change, there is absolutely no reason for the router function to be async. So this is how it should look app.post("/login", (req, res, next) => {...
You're not sending a response back to the caller of /login. So when you test, it just hangs there until you cancel your request. You should add res.json({msg: 'ok'}) below console.log("First function call : ", docs);
And finally, mongoose is an awesome, promise-based library. Why not use its promise capability? It will greatly clean up your code. Here is how I would re-write your code:
app.post("/login", (req, res, next) => {
users.find({email:"xyz#gmail.com"})
.then(docs => {
console.log(docs);
res.json(docs);
})
.catch(e => {
console.log(e);
next(e);
})
})

Get data from mongoDB collection to ejs

I was learning how to use MongoDB atlas. I connected the database with my node app and I am also able to add data to it. The only problem that I am facing is with ejs. I am not able to retrieve my filePath and title from my collection, even though I was able to log all of the data in my collection but I am stuck at how can I get title and filePath from my collection and use the data on my front-end. Here is my code:
app.js:
mongoose.connect(
"mongodb+srv://<name>:<password>t#cluster0.cqqda.mongodb.net/proDB?retryWrites=true&w=majority"
);
const connectionParams = {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
};
mongoose.set("useCreateIndex", true);
const dbName = "proDB";
const userSchema = new mongoose.Schema({
title: String,
filepath: String,
});
userSchema.plugin(findOrCreate);
const User = new mongoose.model("User", userSchema);
app.get("/", function (req, res) {
User.find({}, function (err, foundItems) {
console.log(foundItems.title);
});
res.render("index");
});
app.post("/upload", function (req, res, err) {
const user = User({
title: req.body.podcastTitle,
filepath: req.body.filePath,
});
user.save();
res.redirect("/admin-login");
});
index.ejs
<% newListItems.forEach(function(item){ %>
<div class="video-div">
<p><%=item.title%></p>
</div>
<% }) %>
You need to pass the variables you want to display to the res.render method:
res.render(view [, locals] [, callback])
Renders a view and sends the rendered HTML string to the client. Optional parameters:
locals, an object whose properties define local variables for the view.
callback, a callback function. If provided, the method returns both the possible error and rendered string, but does not perform an automated response. When an error occurs, the method invokes next(err) internally.
To make your code work, move the render function call inside the query callback, and pass the found users to it:
app.get("/", function (req, res) {
User.find({}, function (err, foundItems) {
console.log(foundItems.title);
res.render("index", {newListItems: foundItems});
});
});

Node.js is not giving any response and keep loading

If I am using this function I am getting proper response.
router.get('/', function(req, res, next) {
var products = Product.find();
res.render('shop/index', { title: 'Shopping-Cart', products: products });
});
If I am using below function my local server is not giving any response and keep loading.
router.get('/', function(req, res, next) {
Product.find(function (err, docs){
res.render('shop/index', { title: 'Shopping-Cart', products: docs });
});
});
Help me to solve this problem.
Try this. Add match object to find method.
router.get('/', function(req, res, next) {
Product.find({}, function (err, docs){
res.render('shop/index', { title: 'Shopping-Cart', products: docs });
});
});
The second one is simply wrong. This whole thing :
function (err, docs){
res.render('shop/index', { title: 'Shopping-Cart', products: docs });
}
is being passed to the find() method as a parameter.It makes absolutely no sense
Correct would be this:
Product.find().then(docs=>{
res.render('shop/index', { title: 'Shopping-Cart', products: docs })
}).catch(err=>console.log(err))
Since you haven't specified the database you are using, I'll assume something similar to MongoDB. The first parameter to the find operation must be a query object if any.
Documentation
So, you can tweak your code in any of the ways like this:
var products = await Product.find(); // Using async-await
res.render('shop/index', { title: 'Shopping-Cart', products: products });
Product.find({}, function(err, products) { // Using callbacks
res.render('shop/index', { title: 'Shopping-Card', products: products });
}
Product.find().then(function(products) { // Using Promises
res.render('shop/index', { title: 'Shopping-Card', products: products });
}

Trouble passing mongoose variables to pug template through express

I have a User model through Mongoose, and I'm trying to create a simple CRUD API, starting with the Users part, problem is that my "index," and "create" routes seem to be working but the detail page won't seem to accept the variable being passed to it, and I can't render things on the page.
My User schema is very simple for now, just to get the API working (./models/user.js)
const userSchema = new Schema({
name: {
type: String,
maxlength: 50,
minlength: 2,
trim: true
}
})
The controllers for the routes that DO work look like this (./controllers/user_controller.js)
exports.index = function(req, res, next) {
User.find({}, (err, users) => {
res.render('userindex', {users: users})
})
}
exports.new = function(req, res, next) {
newUser = new User({ name: req.body.name })
newUser.save((err, user) => {
if (err) res.send(err)
res.redirect('/users')
})
}
exports.addUser = function(req, res, next) {
res.render('newuser')
}
The routes look like this so far (./routes/userRouter.js)
I do recognize that the routes for add and new are reversed, it'll be fixed.
userRouter.get('/', userController.index)
userRouter.get('/new', userController.addUser)
userRouter.post('/add', userController.new)
userRouter.get('/:id', userController.detail)
The only thing left is the broken controller: (./controllers/user_controller.js)
exports.detail = function(req, res, next) {
User.find({'_id': req.params.id}, (err, user) => {
if (err) res.send(err)
res.render('userdetail', {user: user})
})
}
And the template that won't seem to receive the data. (./views/userdetail.pug)
p #{user.name}
Find returns an array, so there's no user to template. Either template the first item on the collection:
res.render('userdetail', {user: user[0]})
or use .findOne instead.

Express node.js with mongoose CRUD strange behavior.

I'm starting my adventure with NodeJS. I've choose express web framework with mongoose database. As part of my front-end I'm using AngularJS.
First the front end, basic form args passing to /api/user.
$scope.form = {};
$scope.submitUser = function () {
console.log($scope.form);
$http.post('/api/user', $scope.form).
success(function(data) {})
.error(function(data) {});
};
$scope.form equals to:
Object {name: "foo", surname: "bar", email: "foobar#bar.foo"}
Then we got the back-end, where I start with default user schema:
var userSchema = new mongoose.Schema({
name : String,
surname : String,
email : String
});
var User = mongoose.model('User', userSchema);
And the api post handler:
app.post('/api/user', function (req, res) {
User.create({
name : req.name,
surname : req.surname,
done : false
}, function(err, user) {
if (err)
res.send(err);
res.json(user);
});
});
And the result of that instead of object is just id with __v:
__v: 0
_id: "536e218351b1182d0f000001"
PS. This one is magic, I have completly no idea why this is happening:
Those records above __v and _id, are not being save anywhere (show collections, and find() on each of those results in null). But when I run
User.find(function(err, users) {
if (err)
res.send(err)
res.json(users);
I get few records (previous tries of passing this form) with it's __v and _id.
Connection looks like this:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:1/test');
Thanks for any tips, explanation to that. Sorry for my lack of knowledge but I really tried.
Have a nice day! ;)
Assuming that you send the json object in the body (payload) of POST from client, The server should access the value as req.body.name, not req.name
app.post('/api/user', function (req, res) {
User.create({
name : req.body.name,
surname : req.body.surname,
done : false
}, function(err, user) {
if (err)
res.send(err);
res.json(user);
});
});
Make sure you pass body-parser middleware to express:
var express = require('express')
var app = express()
app.use(express.bodyParser()); // for express 3.x
or for express 4.x
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser()); // for express 4.x
In my case it does not work. Why?
I am getting the value from req.body.name
If I log it console.log(req.body.name); I get the value on my console.
POST:
{ name: 'typing any name', status: null }
typing any name
So the workflow between my frontend (angular.js), the form and the backend (node.js, express, mongoose) seems to work. Now I POST the value, but I get an empty object in my mongoDB.
{"_id":"543a50a974de6e2606bd8478","__v":0}
app.post('/api/offers', function (req, res){
var offer;
console.log("POST: ");
console.log(req.body);
console.log(req.body.name);
offer = new OfferModel({
name: req.body.name,
value: req.body.value,
title: req.body.title,
content: req.body.content,
});
offer.save(function (err) {
if (!err) {
return console.log("created offer" + req.body.name);
} else {
return console.log(err);
}
});
return res.send(offer);
});
And here is the model:
var offerSchema = mongoose.Schema({
offer : {
name : String,
value : String,
title : String,
content : String,
image : String,
start : String,
end : String,
targets : String,
beacons : String,
published : String
}
});
var OfferModel = mongoose.model('Offer', offerSchema);

Resources