I'm using ejs to try to output a username from req.user in a node express app, but it doesn't seem to be working.
This is where my username and password come in:
app.get('/', function(req, res) {
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: req.user
});
console.log("req.user:", req.user);
});
At this point, I can see req.user in terminal displayed like this:
req.user: [ { _id: 5890f8a97ef995525d4b78cd,
username: 'dave',
password: 'somepassword',
__v: 0 } ]
This is what I have in index.ejs:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<head>
<body>
<% if (!isAuthenticated) { %>
Log in here
<% } else { %>
Hello, <%= user.username %>!
Log out
<% } %>
</body>
</html>
And this is the login form:
<!DOCTYPE html>
<html>
<head>
<title>Passport</title>
<head>
<body>
<form action="" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="submit" value="Login">
</form>
</body>
</html>
I initially had this in my index.ejs, but still did not output username.
Hello, <%= user.name %>!
Would appreciate any help.
Based on what your terminal displayed, it looks like req.user is an array containing objects, which means that you would need to access one of the elements in the array before accessing the object's properties.
Therefore <%= user.username %> would be <%= user[0].username %>:
<% if (!isAuthenticated) { %>
Log in here
<% } else { %>
Hello, <%= user[0].username %>!
Log out
<% } %>
Or you could just update the web service to pass in the first element in the user array:
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: req.user[0]
});
<% if (!isAuthenticated) { %>
Log in here
<% } else { %>
Hello, <%= user.username %>!
Log out
<% } %>
You may also want to check if the user array contains any elements to prevent any errors from being thrown if it doesn't:
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: (req.user && req.user.length) ? req.user[0] : {}
});
Related
//user.js
I created the following model Schema with mongoose:
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
ThisSetup: [{name: String, quote: String}]
});
module.exports = mongoose.model("User", UserSchema);
In the mongoDB I can see in the terminal, that this concept is working fine, but if I try to display name property with ejs the following way, ids are displayed, but the names not:
//userid.ejs
<% User.forEach(function(User){ %>
<div class="row">
<p><%= User._id %> <%= User.ThisSetup.name%></p>
</div>
<% }); %
This way I see in the browser the names and the quotes too:
<%= User.ThisSetup %>
How can I reach just the names?
Thank you for in advance
Thanks!
The solution:
<%= User.thisSetup[0].name %>
How do I use errorMessage object from routes in a partial.I tried this
Route:-
const express = require("express");
const router = express.Router();
const Character = require("../models/character");
// All Character
router.get("/", (req, res) => {
res.render("characters/index");
});
// New Character
router.get("/new", (req, res) => {
res.render("characters/new", { character: new Character() });
});
// Creat
router.post("/", (req, res) => {
const character = new Character({
name: req.body.name,
});
character.save((err, newCharacter) => {
if (err) {
res.render("characters/new", {
character: character,
errorMessage: "Error Creating",
});
} else {
// res.redirect(`characters/${newCharacter.id}`)
res.redirect("characters");
}
});
});
module.exports = router;
layout:-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Test</title>
</head>
<body>
<%- include("../views/partials/header.ejs") %>
<%- include("../views/partials/errorMessage.ejs") %>
<br />
<%- body %>
<br />
</body>
</html>
partial :-
<%= errorMessage %>
it gives me this error:-
ReferenceError: D:\Web_Development\LGS\layouts\layout.ejs:10
8|
9| <body>
>> 10| <%- include("../views/partials/header.ejs") %> <%-
11| include("../views/partials/errorMessage.ejs") %>
12| <br />
13| <%- body %>
D:\Web_Development\LGS\views\partials\errorMessage.ejs:1
>> 1| <%= errorMessage %>
2|
errorMessage is not defined
Maybe should you try to include specifix variables :
<%- include("../views/partials/errorMessage.ejs", {errorMessage}) %>
Or just check the avaibality of your variable as it's in the main layout...
<% if (errorMessage !== undefined) { %>
<%= errorMessage %>
<% } %>
You are passing data from sever to "characters/new.ejs" this file
and now in new.ejs file you have used layouts such as header and errorMessage by using <%- include() %> statement
and to pass data from new.ejs file to this layouts you need to provide second argument to <%- include() %> statement and object of data that you want to pass
so in your example to pass errorMessage to
"../views/partials/errorMessage.ejs" you need to provide
<%- include("../views/partials/errorMessage.ejs", {errorMessage}) %>
then you can use this passed data to your layout like <%= errorMessage %>
if you want to pass more then one data you can do this
<%- include("../views/partials/errorMessage.ejs", {data1, data2, ...}) %>
try this it might be helpful it worked for me !!!!!
<% if(locals.errorMessage != null) {%>
<%= errorMessage %>
<%}%>
I had the same problem... and I solved it by using this:
<%= locals.errorMessage %>
model named Field.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/SuperchainV1', {
useNewUrlParser: true });
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
const db = mongoose.connection;
const FieldSchema = mongoose.Schema({
productID: {
type: String
},
productName:{
type: String
},
fieldLocation: {
type: String
},
farmerName: {
type: String
},
farmerMobile: {
type: String
},
farmerNid: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
const Field = mongoose.model('Field', FieldSchema);
module.exports = Field;
routes index.js
router.get('/dashboard', ensureAuthenticated, (req, res) => {
let field = Field.find({})
.sort({date:'desc'}).exec( (err, field) => {
res.render('dashboard', field);
});
})
dashboard.ejs where i want to display data after fetching
<div class="jumbotron">
<p class="lead">
<% field.productID %>
<% field.productName %>
<% field.fieldLocation %>
<% field.farmerName %>
<% field.farmerNumber %>
<% field.farmerNid %>
</p>
</div>
errors i get "field is not defined"
I want to fetch data from collections fields and display all the data into a ejs page named dashboard i tried this but always get the error field is not defined.
You need to use for loop in ejs template
<% for(var i=0; i < field.length; i++) { %>
<div class="jumbotron">
<p class="lead">
<%= field[i].productID %>
<%= field[i].productName %>
<%= field[i].fieldLocation %>
<%= field[i].farmerName %>
<%= field[i].farmerNumber %>
<%= field[i].farmerNid %>
</p>
</div>
<% } %>
I am just starting with javascript / express / mongodb. As a little starting project I want to do a simple task manager. The todos should be divided by prios. So every entry has it's flag "high", "mid" or "low".
However, I can't manage to show the different entries on the index page.
The error message is: "tasks_low is not defined"
This is the relevant js snippet:
app.get('/', function(req, res){
db.tasks.find({prio: 'high'}, function (err, highs) {
res.render('index', {
title: 'Aufgaben High:',
tasks: highs
});
})
});
app.get('/', function(req, res){
db.tasks.find({prio: 'low'}, function (err, lows) {
res.render('index', {
title: 'Aufgaben Low:',
tasks_low: lows
});
})
});
This is my index.ejs file:
<h1>Prio High</h1>
<ul>
<% tasks.forEach(function(tasks){ %>
<li><%= tasks.task %> <%= tasks.prio %> - <a class="deleteUser" data-id="<%= tasks._id %>" href="#">x</a></li>
<% }) %>
</ul>
<br><br>
<h1>Prio Low</h1>
<ul>
<% tasks_low.forEach(function(tasks_low){ %>
<li><%= tasks_low.task %> <%= tasks_low.prio %> - <a class="deleteUser" data-id="<%= tasks_low._id %>" href="#">x</a></li>
<% }) %>
</ul>
However, when I compile to different views it all works well!
app.get('/tasks_high/', function(req, res){
db.tasks.find({prio: 'high'}, function (err, highs) {
res.render('index', {
title: 'Aufgaben High:',
tasks: highs
});
})
});
app.get('/tasks_low/', function(req, res){
db.tasks.find({prio: 'low'}, function (err, lows) {
res.render('index', {
title: 'Aufgaben Low:',
tasks_low: lows
});
})
});
Just create a collection entry with title + task:
// Task collection structure
var Task= mongoose.model('Tasks', {
title: String,
priority: String,
});
And then filter each task based in its priority as you're doing, but using the same collection
Here is the page I am trying to render
<% include ../partials/boilerplate %>
<div class="triviaContainer">
<h1>GAME TIME!!! </h1>
<% var i =0; data.forEach(question =>{ i+=1 %>
<div class="questionRow">
<div> <%= question.question %></div>
</div>
<div class="questionRow1">
<div clicked="" id="correctanswer<%=i %>" class="correctAnswer" > A: <%= question.correct_answer %></div>
<div clicked="" id="incorrectanswer<%=i %>" class="incorrectanswer<%=i %>" >B: <%= question.incorrect_answers[0].incorrect_answer %></div>
</div>
<div class="questionRow2">
<div clicked="" id="secondincorrectanswer<%=i %>" >C: <%= question.incorrect_answers[1].incorrect_answer %></div>
<div clicked="" id="lastanswer<%=i %>" >D: <%= question.incorrect_answers[2].incorrect_answer %></div>
</div>
<% }) %>
<form class="gameForm" method='POST' action='/trivia/score'>
<input type="hidden" name="points" value="" id="points"/>
<input type="hidden" name="gameid" value="<%= data[0].game_id %>"/>
<input type="hidden" name="questions" value="<%= data[0].number_of_questions %>"/>
<input type="submit" value="GET RESULTS">
</form>
</div>
<script type="text/javascript" src="javascript/triviaGameScript.js"></script>
<% include ../partials/end %>
I am rendering the questions in the question.question portion of the foreach function. If you look at this screen shot, the last question has a quote html entity. I have several questions that have these entities and would like to find an npm package to decode them.
Here is the controller where I am requiring html-entities npm package
const triviaModel = require('../models/trivia');
const authHelpers = require('../services/auth/auth-helpers')
const Entities = require('html-entities').XmlEntities;
const entities = new Entities();
const triviaapiController = {};
triviaapiController.index = (req, res) => {
console.log(req.body.game_id);
triviaModel.GetGame(req.body.game_id)
.then(data =>{
console.log(data);
res.render('trivia/trivia-index', {
data: data,
});
})
.catch(err => {
console.log(err);
res.status(500).json({ err });
});
}
the data portion in the trivia-index promise is where the questions and answers are stored.
here is the documentation for this particular package. https://www.npmjs.com/package/html-entities I am not specifically sure how to use it. Should I apply it in the ejs file, or to the data object that is getting passed in. Any help would be much appreciated!
You code use the package like that:
triviaapiController.index = (req, res) => {
console.log(req.body.game_id)
triviaModel.GetGame(req.body.game_id)
.then(data => {
console.log(data)
var decodedData = []
for (var q of data) {
var decodedQ = {
question: entities.decode(q.question),
correct_answer: q.correct_answer,
incorrect_answers: q.incorrect_answers
}
decodedData.push(decodedQ)
}
res.render('trivia/trivia-index', {
data: decodedData
})
})
.catch(err => {
console.log(err)
res.status(500).json({ err})
})
}