How to pass database values from node js to ejs file - node.js

Hi I am trying to add search bar in main page and search in the main page without changing to another page.
My user.js file
if (req.method == 'get'){
var username = req.query.username;
Users.find({username}, function (err, user) {
if(err) {
return res.render(template:'index')
}
res.render({template:'index', { user : user}});
})
}
my index.ejs file
<div class="search-user">
<% for user in user { %>
<div>
<p>Username : <%= user.username %></p>
<p>Age <%= user.age %></p>
<p>Status <%= user.status %></p>
</div>
<% } %>
</div>
This is giving me errors. May i know what did i do wrong?

Add a console message and check if you are getting data in user object
if (req.method == 'get'){
var username = req.query.username;
Users.find({username}, function (err, user) {
if(err) {
console.log('error', error)
return res.render('index')
}
console.log('user', user)
res.render('index', { user });
})
}
Further before iterating user of object just check something like this:
<div>
<p>Username : <%= JSON.stringfy(user) %></p>
</div>
By this you will get to know where error is being occured.

Refer to Res.render()
if (req.method == 'get'){
var username = req.query.username;
Users.find({username}, function (err, user) {
if(err) {
return res.render('index')
}
res.render('index', { user });
})
}

Related

How to show follow/buttons in ejs

Im trying to make a user profile page where a user can follow another user.
my routes are fine
but then i wanted to ask is if a user clicks on follow. Only the unfollow button will be shown. if i unfollow the follow button will be shown.
these are my codes
router.get('/follow/:id', isLoggedIn, async function(req, res, next) {
try {
const user = await User.findById(req.params.id);
if (!user) {
req.flash("error", "User does not exist");
res.redirect('back')
return res.status(404).json({ error: 'User does not exist' });
}
if (user.followers.indexOf(req.user.id) !== -1) {
req.flash("error",`You're already following ${user.local.username}` )
res.redirect('back')
return res.status(400).json({ error: `You're already following
${user.local.username}` });
}
user.followers.addToSet(req.user.id);
await user.save();
const users = await User.findById(req.user.id);
users.following.addToSet(user.id);
await users.save();
req.flash("success", "User added")
return res.redirect('back')
} catch (err) {
return next(err);
}
});
router.delete('/follow/:id', isLoggedIn, async function(req, res) {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
const following = user.followers.indexOf(req.user.id);
if (following === -1) {
return res.status(400).json({ error: `You're not following
${user.username}` });
}
user.followers.splice(following, 1);
await user.save();
const userLogged = await User.findById(req.user.id);
const positionUnfollow = userLogged.following.indexOf(user.id);
userLogged.following.splice(positionUnfollow, 1);
await userLogged.save();
req.flash('success', `You have sucessfully unfollowed
${user.local.username || user.facebook.name}`)
return res.redirect("back");
} catch (err) {
return next(err);
}
});
my ejs page
<div class="follow justify-content-center">
<% user.followers.forEach(function(follower) { %>
<% if(currentUser && currentUser._id.equals(follower.id)) { %>
<form id="delete-btn" action="/users/follow/<%= user.id%>?
_method=DELETE" method="POST">
<button class="btn btn-danger"><i class="fas fa-user-slash">
</i></button>
</form>
<% } %>
<% }) %>
</div>
<% user.following.forEach(function(follow) { %>
<% if(currentUser && follow._id !== user._id) {%>
<a href="/users/follow/<%= user.id %>"><button class="btn btn-
primary">
<i class="fas fa-user-plus"></i></button></a>
<% } %>
<% }) %>
<div class="card-footer text-center">
<div class="social-media">
<i class="fab fa-facebook"></i>
<i class="fab fa-twitter-square"></i>
<i class="fab fa-instagram"></i>
</div>
</div>
</div>
</div>
my user schema
followers: [
{
type: mongoose.Schema.ObjectId, ref: 'User'
}
],
following: [
{ type: mongoose.Schema.ObjectId, ref: 'User'
}
],
the problem now is if i follow a user the unfollow button will appear but the follow button won't go away.
also if i did a <%=user._id%> and <%=follow.id%> the values are the same but not sure why the environment variables didn't work.

What is the proper way to check if id exists or not ? (ejs, mongoose)

If i have code like:
index.js
app.get('/link/:id', (req, res) => {
collection.find({ _id: req.params.id }, (err, collection) => {
if(err) res.send(err)
else {
res.render('link', { collection: collection });
}
link.ejs
<% if(collection != 'undefined') { %>
<li><%= collection.userName %></li>
<li><%= collection.address %></li>
<% }else{ %>
<p>Data not found</p>
<% } %>
But it also shows this error:
error:
Cannot read property 'userName' of undefined
so what is the solution?

How to display all users database (mongodb) details on .ejs file

I have a node.js website that i build with this tutorial:
https://scotch.io/tutorials/easy-node-authentication-setup-and-local
now i want in one of my views to print/display all users data.
in routes.js:
var User = require('../app/models/user'); //the connection to users database
app.get('/profile', isLoggedIn, function (req, res) {
res.render('profile.ejs', {
Users: User // get the user out of session and pass to template
});
});
and this is in my profile.ejs file:
<ul>
<% Users.forEach( function(err, user) { %>
<li><%= user %> </li>
<% }); %>
i get an error: "undefined is not a function" because of the <% Users.forEach( function(err, user) { %> line
what am i doing wrong?
You need to actually query the user collection via the model's find() query function which will return an array of user documents when executed, i.e.
var User = require('../app/models/user'); //the connection to users database
app.get('/profile', isLoggedIn, function (req, res) {
User.find({}).exec(function(err, users) {
if (err) throw err;
res.render('profile.ejs', { "users": users });
}
});
then render the list of user documents in your profile.ejs as:
<% users.forEach(function (user) { %>
<li>
<h1><%= user.name %></h1>
</li>
<% }) %>

Error: can't set header after they are sent

I have two schemas, one for user and one for friendship system (follow system)
module.exports = mongoose.model('User', {
email: {
type: String,
unique: true,
lowercase: true
},
password:String,
profile: {
fullname: String,
gender: String,
role: {type: String, default: 'Autorizado'},
country: String },
});
and this for friend system
module.exports = mongoose.model('Friendship', {
follower: String,
followed: String
});
I'm using passport to auth my users... the problem is that I want lo load the user information and the friend information related to the user globally using res.locals I make this happen using 2 functions in login post route....
router.post('/login', userController.postLogin,friendController.getFollow);
this is my postlogin function
exports.postLogin = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) return next(err);
if (!user) {
req.flash('errors', { msg: info.message });
return res.redirect('/login');
}
req.logIn(user, function(err) {
if (err) return next(err);
req.flash('success', { msg: 'Success! You are logged in.' });
res.redirect('/');
});
})
(req, res, next);
};
When I try to execute this code everything goes fine but when I log in I get the header error please how can I solved this or other way to get the user and follow information and use it in every view?.
EDIT 3: only works in the next two views
Single User page
<%= info.profile.fullname %>
<br>
<%= info.email %>
<br>
<%= info.profile.country %>
<br>
<%= user.follow %>
<br>
<% if(user && (user._id != info.id)){ %>
<br>
<form action="/follow/<%= info._id %>" method="post">
<button type="submit">Follow</button></form>
<%}%>
<br>
atras
List of Registered User
<%if (user) {%>
<h1>Hola <%= user.profile.fullname %> </h1>
<%}%>
<br>
<% users.forEach(function (user) {%>
<p><%= user.profile.fullname %></p>
<%});%>
Home
This is my index and in this view the user.follow doesn't work
<%if (!user) {%>
sign up
<br>
login
<%} else { %>
<h1>Hola <%= user.profile.fullname %> Eres lo Maximo</h1>
perfil
<br>
Logout
<br>
<%}%>
<br>
Lista de Usuarios
EDIT 4: new deserializeUser config.
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
FF.find({ follower:id }, function(err, follow) {
user.follow = follow;
});
done(err, user);
});
});
EDIT 5: This is my route code
router.get('/', function(req, res) {
res.render('index');
});
router.get('/login', userController.getLogin);
router.post('/login', userController.postLogin);
router.get('/logout', userController.logout);
router.get('/signup', userController.getSignup);
router.post('/signup', userController.postSignup);
router.get('/profile', passportConf.isAuthenticated, userController.getAccount);
router.post('/profile', passportConf.isAuthenticated, userController.postUpdateProfile);
You had friendController.getFollow which would've worked only for the request of '/login' page, so the follow object wouldn't have been persistently available on other routes. To fix that you had to put all that code inside the passport.deserializeUser function.
Inside the passport.deserializeUser function you could only call done once so you had to put the logic to find follow inside the callback of User.find so that you could attach follow to user.
This allowed you to remove the friendController.getFollow from your '/login' route which I think was the cause of your error.

how to send a flash message with res.redirect('/') sails js

How to send a flash message with res.redirect('/') in Sails?
When i check some condition in a controller then I want to redirect to another url, passing along a flash message.
I am new to Sails, so any help will be appreciated.
Controller action:
module.exports ={
index: function (req, res) {
if(req.param('key')){
req.flash('message', 'welcome key is present');
res.redirect('/view/');
} else {
req.flash('message', 'welcome key is not present');
res.redirect('/');
}
}
}
Thanks in advance.
Your code looks fine for the controller. In your view, you can access the flash message as req.flash('message'), so in an .ejs file for example it would be <%- req.flash('message') %>
What I find better for any redirect with data, is to set the http code to 307. It'll redirect with post/put/delete data.
req.flash('message');
res.redirect(307, '/');
An other solution would be to pass the message parameter in the route where you render the redirected template.
So let's take your example (slightly modified):
module.exports ={
index: function (req, res) {
if(req.param('key')){
req.flash('info', 'welcome key is present' );
res.redirect('/view/');
} else {
req.flash('info', 'welcome key is not present');
res.redirect('/');
}
}
}
Then in the route for 'view', you'll have something like this:
app.get('/view', function(req, res){
var messages = {};
if (typeof res.locals.messages.info != 'undefined'){
messages = res.locals.messages.info;
}
res.render('view.ejs', {
messages: messages
});
});
Then in your view.ejs:
<% if (typeof messages != 'undefined' && messages.length > 0) { %>
<% for (var i in messages) { %>
<div class="alert alert-info">
<%= messages[i] %>
</div>
<% } %>
<% } %>
Also in your main server.js file:
app.use(function(req, res, next) {
res.locals.messages = req.flash();
});

Resources