Send multiple variables through render with Express - node.js

Maybe a stupid question but, is it possible to send multiple variables through res.render() in Express ?
Because, when I do
res.render('index', { title: 'Express', name: 'Arnaud' });
I've all this pretty error telling me name is not defined.
In this view
extends layout
block content
h1 Salut #{name}
p Welcome to #{title}
Any idea ?

In route:
res.render("index", { data: { title: "Express", name: "Arnaud" } })
In view:
<%= data.title %>
<%= data.name %>

I also got this problem for a long time and found a workaround: to pass a variable you just should do
res.locals.title = "Express";
res.locals.name = "Arnaud"
res.render("index");
The both variables Express and Arnaud will be given to the EJS context

Weird thing is weird : I regenerated a new Express project and everything is fine...

Related

Use Async function to print value in ejs view Express js

I passed the model from controller to use it in view, but it seems like printing values using Async functions is not possible in a view. what could be the suitable way to use a model to print inside an async function in a view?
I need to get the userImage from user table.
(ps: use of console.log(userImage) in the same place is working, it's driving me crazy. please help me)
<img src="<% userModel.findById(postData.uid,function(err,user) {%> <%=user.userImage%> <% }) %>" class="mx-2">Anmol D. Pradhan
At first, that's absolutely not the best practice.
You should do something like that:
// ...
const userModel = require('/your-path-to/userModel');
app.get('/your/url', async (req, res) => {
const user = await userModel.findById(uid);
res.render('/youpage.html', {
user: user
});
});
<!-- Here's your EJS template -->
<img src="<%= user.userImage %>" class="mx-2">Anmol D. Pradhan
That's just an example. I don't know how actually your routes structured, but I hope that will help.

Redirect and render template with new variables

I will show my code first in order to be clear.
router.get("/add", (req, res)=>{
res.render("user/add.ejs");
});
router.put("/add/pi", (req, res)=>{
if(condition){
//do something
}else{
res.redirect("/user/add");
//res.render("user/add.ejs", {error: "At least one field should be filled in order to submit the form", type: "form error","location": "form-container"});
}
});
Ejs:
<% if(error){ %>
<small id="personalinformationError" class="form-text text-danger"><%= error %></small>
<% }%>
I want to be able to render the ejs template with the object in the render() in the comment. I tried to render it like in the comment without redirect() and it shows an error whenever I mention the variable name. The error goes like variable is not defined.
Thank you in advance.

Use console.log in EJS

Is it possible to use console.log in a node / ejs template? It doesn't seem to do anything when I try, even something as simple as:
<% console.log('test') %>
I've also tried:
<%= console.log('test') %>
Nothing shows up in the console.
I think you are expecting it to show in the developer console. It will not show up there.
console.log() in EJS file will show the log in the terminal where the server is running.
This worked perfectly
<% console.log('heheeh', JSON.stringify(doc, null, '\t')) %>
console.log() is working fine, but its log does not display in dev tools.
So, check your terminal first:
<% console.log("test") %>
It's perfect.
console.log(test) in ejs file will show the log in the terminal
And if you want to see test object or value in browser than try
<%= test %>
This will show objects as string
I know this is a really old thread, but I just had this issue and this is what I ended up doing:
<% var data = JSON.stringify(htmlWebpackPlugin) %>
<script>
console.log(<%= data %>)
</script>
It doesn't look pretty, but it works
Code
Output
<% console.log(posts) %>
NB: Make sure you define your variable in any other file you have eg app.js file...
let posts = [];
app.get("/", (req, res) => {
res.render("home", {
posts: posts
});
});
OUTPUT
Click me
first, Your home route inside your index.js/server.js/app.js, render a variable you want console log in another ejs file; in the code below, nposts is a variable or an array;
app.get("/",function(req,res){
res.render("home", {posts: nposts});
then in your ejs file, in this example in the home.ejs console.log in the <% %> tags
<% console.log(posts); %>
send from serve-side
let item = [arr1, arr2, arr3]
res.send("index", { item })
in client-side
example
use in script
console.log('<%- item %'>
arr1,arr2,arr3
console.log('<%- JSON.stringify( item ) '%>
["arr1","arr2","arr3"] //text
var newArray = JSON.parse('<%- JSON.stringify( item )%>')
console.log(newArray )
<% { %>
<script>console.log('hello')</script>
<% } %>
this code is work well.
create { } by <% %> from ejs.
We can add javascript code inside { }.
The simple answer would be:
If you are in your home route and you want to test any condition you would have to use ejs tags. inside the tags drop your normal console.log.
<% console.log(test) %>

Nested resources in railway.js: Says cannot POST

I am trying out an MVC framework called railway.js (which sits on top of Node, Express, Mongoose, and Mongo).
I'm trying to get nested resources to work. I did the following scaffolding commands:
railway g scaffold user name email description
railway g scaffold setup title description
Then I changed the routes.js file to:
exports.routes = function (map) {
map.resources('users',function(user) {
user.resources('setups');
});
});
Doing railway r gives what I hoped for:
user_setups GET /users/:user_id/setups.:format? setups#index
user_setups POST /users/:user_id/setups.:format? setups#create
new_user_setup GET /users/:user_id/setups/new.:format? setups#new
edit_user_setup GET /users/:user_id/setups/:id/edit.:format? setups#edit
user_setup DELETE /users/:user_id/setups/:id.:format? setups#destroy
user_setup PUT /users/:user_id/setups/:id.:format? setups#update
user_setup GET /users/:user_id/setups/:id.:format? setups#show
users GET /users.:format? users#index
users POST /users.:format? users#create
new_user GET /users/new.:format? users#new
edit_user GET /users/:id/edit.:format? users#edit
user DELETE /users/:id.:format? users#destroy
user PUT /users/:id.:format? users#update
user GET /users/:id.:format? users#show
When I start up the server, add a user (happens to be 4e4b61e39f0d60d834000002), then go to http://localhost:3000/users/4e4b61e39f0d60d834000002/setups/new, it says I "cannot POST".
What am I missing? What's a good debugging approach?
I also tried adding an element into the UserSchema object: setups: [SetupSchema]. (Shouldn't we have to do this?)
Thanks in advance.
in your setup_controller:
before(loaduser);
...
function loadUser () {
User.findById(req.params.user_id, function (err, user) {
if (err || !user) {
redirect(path_to.users);
} else {
// this is where we make the actual user object accessible inside the view templating
this.user = user;
next();
}
}.bind(this));
}
in your setup/form.jade:
- form_for( setup, { method: 'POST', action: path_to.user_setups(user) }, function(form){
//layout your form
- });
Look at file app/views/setups/new.ejs:
<h1>New setup</h1>
<% form_for(setup, {action: path_to.setups, method: 'POST', id: "setup_form"}, function (form) { %>
<%- partial('setups/form.ejs', {locals: {form: form, setup: setup}}) %>
<%- form.submit('Create setup') %> or
<%- link_to('Cancel', path_to.setups) %>
<% });%>
It refers to not existing route path_to.setups, you have to change it to correct route path_to.user_setups:
<h1>New setup</h1>
<% form_for(setup, {action: path_to.user_setups(user), method: 'POST', id: "setup_form"}, function (form) { %>
<%- partial('setups/form.ejs', {locals: {form: form, setup: setup}}) %>
<%- form.submit('Create setup') %> or
<%- link_to('Cancel', path_to.setups) %>
<% });%>
So, you will POST to /users/.../setups instead of POST to /users/.../setups/new.
Please note that you need pass user as first argument of path_to helper, so railway will build correct route for you.

express+jade: provided local variable is undefined in view (node.js + express + jade)

I'm implementing a webapp using node.js and express, using the jade template engine.
Templates render fine, and can access helpers and dynamic helpers, but not local variables other than the "body" local variable, which is provided by express and is available and defined in my layout.jade.
This is some of the code:
app.set ('view engine', 'jade');
app.get ("/test", function (req, res) {
res.render ('test', {
locals: { name: "jake" }
});
});
and this is test.jade:
p hello
=name
when I remove the second line (referencing name), the template renders correctly, showing the word "hello" in the web page. When I include the =name, it throws a ReferenceError:
500 ReferenceError: Jade:2 NaN. 'p hello' NaN. '=name' name is not defined
NaN. 'p hello'
NaN. '=name'
I believe I'm following the jade and express examples exactly with respect to local variables. Am I doing something wrong, or could this be a bug in express or jade?
app.set ('view engine', 'jade');
app.get ("/test", function (req, res) {
res.render ('test', {
name: "jake"
});
});
you can do it like this.
Rather than =, you can use #{variable-name}. Here is an example of how I'm using it:
This will render a page, with a menu for navigation. Passing the page title in each time the page is loaded, ofcourse you will need to create an app.get function for each page.
App.js
var navigation = {
home : {
uri : "/",
url : "index",
title : "Home"
},
lab : {
uri : "/lab",
url : "lab",
title : "Lab"
},
profile : {
uri : "/profile",
url : "profile",
title : "Profile"
},
timetable : {
uri : "/timetable",
url : "timetable",
title : "Timetable"
}
}
app.get(navigation.profile.uri, function(req, res){ //Profile
res.render(navigation.profile.url, {
title: navigation.profile.title,
navigation: navigation
});
});
profile.jade
section#page-content
h1#page-title #{title}
p Welcome to #{title}
layout.jade
!!! 5
html
head
title= title
link(rel='stylesheet', href='/stylesheets/reset.css')
link(rel='stylesheet', href='/stylesheets/style.css')
body
header#site-header
nav#site-navigation
!= partial("partials/navigation")
section!= body
footer#page-footer
I think the error is sometime caused due to the request by the browser for favicon.ico.
Try adding these lines to the layout.jade head to link the icon
link(rel='icon', href='/images/siteicon.png')
This removed the same error that I was getting

Resources