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 %>
Related
I have a views folder structure and a ejs file profile_60113.ejs like this
views
docs
profile_60113.ejs
I can dynamically render the file like this (where data.groupID == 60113):
<%- include("docs/profile_" + data.groupID); %>
But how can I first check if the file exists? I tried this:
<% if (fs.existsSync("views/docs/profile_" + data.groupID)) { %>
<%- include("docs/profile_" + data.groupID); %>
<% } %>
Or ...
<% if (fs.existsSync("docs/profile_" + data.groupID)) { %>
<%- include("docs/profile_" + data.groupID); %>
<% } %>
But didn't work ...
const fs = require('fs') is included in the controller and fs:fs is rendered
What works is e.g.:
Option 1 (Synchronously): Template
Serverside:
const fs = require('fs');
var getGroupID = 60113;
res.render('docs', {
page: setPage,
data: {groupID: getGroupID},
fs: fs
});
Template:
<% if (fs.existsSync("views/docs/profile_" + data.groupID + ".ejs")) { %>
<%- include("docs/profile_" + data.groupID); %>
<% } %>
Option 2 (Synchronously): Serverside & Template
Serverside:
const fs = require('fs');
var getGroupID = 60113;
var getProfile;
if (fs.existsSync("views/docs/profile_" + getGroupID + ".ejs")) {
getProfile = true;
} else {
getProfile = false;
}
res.render('docs', {
page: setPage,
data: {groupID: getGroupID},
profile: getProfile
});
Template:
<% if (profile) { %>
<%- include("docs/profile_" + data.groupID); %>
<% } %>
Option 3 (Asynchronous I/O): Serverside & Template
Serverside:
...
var getProfile;
try {
await fs.promises.access("views/docs/profile_" + getGroupID + ".ejs");
getProfile = true;
} catch (error) {
console.log(error);
}
...
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>
<% } %>
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})
})
}
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] : {}
});
I'm tryong to use event_calendar gem and i follow this 3 guides
http://andolasoft.wordpress.com/2013/01/09/how-to-implement-event-calendar-in-rails-app/
https://github.com/elevation/event_calendar#static-files
https://github.com/elevation/event_calendar/wiki/Quickstart-from-scratch
I think that my problem is about the including of the stylesheet and of the javascript.
I can't understand the step of including because each guides say something different.
Heres the error
TypeError in Calendar#index
Showing /home/user/work/aptana_1/spree_calendar/app/views/calendar/index.html.erb where >line #6 raised:
no implicit conversion of nil into Hash
Extracted source (around line #6):
<h1>Calendar</h1>
<%= event_calendar %>
>Rails.root: /home/user/work/aptana_1/spree_calendar
>
>Application Trace | Framework Trace | Full Trace
>app/helpers/calendar_helper.rb:24:in `event_calendar'
>app/views/calendar/index.html.erb:6:in >`_app_views_calendar_index_html_erb___345437905_81942130'
>Request
>
>Parameters:
>
>{"year"=>"2014",
> "month"=>"07"}
and this is the calendar_helper file
module CalendarHelper
def month_link(month_date)
link_to(I18n.localize(month_date, :format => "%B"), {:month => month_date.month, :year => month_date.year})
end
# custom options for this calendar
def event_calendar_opts
puts("EVENTCALENDAROP")
{
:year => #year,
:month => #month,
:event_strips => #event_strips,
:month_name_text => I18n.localize(#shown_month, :format => "%B %Y"),
:previous_month_text => "<< " + month_link(#shown_month.prev_month),
:next_month_text => month_link(#shown_month.next_month) + " >>"
}
puts"###{#year}"
puts"###{:year.to_s}"
end
def event_calendar
# args is an argument hash containing :event, :day, and :options
puts "EVENT_CALENDAR"
calendar event_calendar_opts do |args|
event = args[:event]
%(#{h(event.name)})
end
end
end
and here is the view
<!-- Probably move the stylesheet to you layout. Also make sure you include the javascript. -->
<%= stylesheet_link_tag "event_calendar" %>
<h1>Calendar</h1>
<%= event_calendar %>
and here is the application layout
<!DOCTYPE html>
<html>
<head>
<title>SpreeCalendar</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true ,'event_calendar'%>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
the problem is within this method:
def event_calendar_opts
puts("EVENTCALENDAROP")
{
:year => #year,
:month => #month,
:event_strips => #event_strips,
:month_name_text => I18n.localize(#shown_month, :format => "%B %Y"),
:previous_month_text => "<< " + month_link(#shown_month.prev_month),
:next_month_text => month_link(#shown_month.next_month) + " >>"
}
puts "###{#year}"
puts "###{:year.to_s}"
end
I believe the two calls to puts at the end are debugging output, but they change the return value of #event_calendar_opts. You should remove the puts or move them to the top:
def event_calendar_opts
puts("EVENTCALENDAROP")
puts "###{#year}"
puts "###{:year.to_s}"
{
:year => #year,
:month => #month,
:event_strips => #event_strips,
:month_name_text => I18n.localize(#shown_month, :format => "%B %Y"),
:previous_month_text => "<< " + month_link(#shown_month.prev_month),
:next_month_text => month_link(#shown_month.next_month) + " >>"
}
end