Sending data to header.ejs using Nodejs - node.js

I send data to my Nodejs pages doing something like:
res.render("mainPage.ejs",{myArray})
However, I have a situation where I want to change set the navbar dropdown values using some values form my database.
I wanted to know if is possibile to send data to every header.ejs file using Nodejs.

Like Handlebars, ejs also has the concept of partials.
Check out the official doc. here:
https://www.includehelp.com/node-js/ejs-partials.aspx
You can pass the data to the views by doing something like this:
router.get('/routeHere', (req,res)=>{
res.render('pages/blog',
{
key1: value1,
key2: value2
});
});
You will then be able to access the object under 'res.render()' in the view.

You don't "send data to a partial". You pass data into your temaplate res.render('mytemplate', { user }) and user is available to each partial you included in mytemplate.ejs. Included partials see their parent template data.

Related

Can I pass data to a handlebars partial?

I'm making a website in Node JS, and want to display something from the database on the website.
When I fetch the data in node, I pass it of to an html page (an hbs file) using express as the second argument in res.render().
However, that html page (hbs file) which I pass the data to, contains a partial, is it possible to pass that same data which was passed to the hbs file, to the partial that is in that hbs file?
Important code for reference:
Passing the data to the hbs file:
app.get('/about',async (req,res)=>{
const names = await Category.find({});
res.render('about',{
categories:names
});
})
Then I'd like to do something like this
{{>header,{{categories}}}} in order to access the categories data in the partial.

Why res.render() doesn't send local variables to the client without template engine?

I need to access the variable user in my client-side that sent by
res.render('home.html', { user: req.user });
without using template engines like pug or ejs
Is that possible?
HTML is not a templating language, so it can't be used to send variables.
res.render() function compiles your template , inserts locals there, and creates html output out of those two things. The syntax is as follows -
res.render(view [, locals] [, callback])
The view argument is a string that is the file path of the view file to render. For this to work, you need a template or view engine .
In html, you can't dynamically pass/insert data variables. That's the main use case for templating engine. They put runtime/dynamic value in html which is what you are probably looking for.
In short, its better to use any template engine like pug,jade,ejs, etc most of which would have almost similar syntax with html to render dynamic html pages. I don't think there's any method (atleast simple enough) to send variables dynamically from server to client in an html page. Using a template engine would be the best choice in your use case.
For eg. you are passing user from server side and most probably want the passed variable to be rendered on the client side. You can just install an view engine like ejs - npm install ejs, set your view engine in app.js - app.use('view engine','ejs'); , and just add this line in the html page where you want to send the variable to client side like - <p> <%= user %> </p> and that's it. Keep your html file in view folder and this would do it.

How to edit jade image field from within Node/Express?

I want to display an image on a webpage on the basis of what the user enters in a form. I have the form defined in abc.jade, and in abc.js I store everything from the form, and generate the image's url and store it in a variable map_img on the basis of the form. How do I set an image's source in jade to point to map_img URL?
abc.js:
sales.save();
markers = [{ 'location': sales.location }]
var gm = require('googlemaps');
var map_img = gm.staticMap(sales.location, 16, '500x400', false, false, markers);
In general, what is the best way to manipulate fields in an HTML/Jade document from node/express?
Im not sure if i get your question right...
There are severals ways to send data.
Mostly described here: http://jade-lang.com/reference/
I usually use #{img_map} or in the case you have to get pure html its better to use !{img_map_html_desc}.
Also, the alternative variant, create #temp div, send data there. Than on the front end js(on window.onload) you can get that data and store to the variable. Don't forget to clear the #temp div after you dont need that anymore.
Once i've used side front-end js module and couldnt find better sollution, than this. Cause that module waited for window.onload, and than started to load itself...

Render partial view with jade on select change

I need to do the following,
I have a <select> (a list of team names), when the user selects a team, I get relevant information re: the team and display it.
How do I do this in jade?
I'm trying the following, (but I'm wrong obviously, I don't see a lot of documentation out there).
Briefly, I'm doing a include test.jade on my main page, and a res.render('test', {team: team_obj});
jade:
h1 #{team}.name
h2 #{team}.homeGround
h3 #{team}.manager
h4 #{team}.aka
nodejs:
collection.findOne(query, function(err, team_obj){
res.render('test', {team: team_obj});
});
I'm getting the information correctly in team_obj.
Get the following error when I run the app,
team is not defined
Now this is happening because test.jade is getting rendered before I feed it the team_obj.
Questions:
1) Am I doing this right? is include the correct way of partially rendering jade views? if yes, how do I make sure it renders only when the user has selected an option?
2) Is there a partial views concept in jade I'm unaware of?
1) you should use #{team.name}
2) you can't change the team object once the selector is changed. the template was rendered once with the database result. - such functionality should be handled by client side JavaScript and AJAX calls. partials in templates are just a way to share common pieces of templates, and its done in Jade via include.
I don't know what you're rendering and including and when.. but id you use a template variable like #{team.name} you have to make sure that the template was rendered with the team object.

How to use a jade template to accept information from multiple sources and display with include statements

I have this template:
.bar
.titleBox
a.title(href=URL) #{title}
Which I want to include multiple times in another page, titles.jade, like so:
#contentBox
include bar
include bar
include bar
And I want each one to have a different value for URL and title.
I have this code in node:
read(function(post){ //post is an array of objects retrieved from a mongodb collection
// I was thinking of using a for loop to iterate through the array
res.render('titles', {title: post[i].title, url: post[i].URL});
How might I achieve my desired outcome?
I'm not sure what these objects represent, but I'll assume for now we are talking about books. If your jade template can get a list of books as a local - e.g. if it's redered like:
res.render('books_index', {books: [{title: 'dune', url: 'http://www.dunenovels.com'},...]})
You can use a mixin. Something like this:
mixin listBooks(books)
each book in books
.bar
.titleBox
a.title(href=book.url)= book.title
later in your template you can render the mixin:
mixin listBooks(books)

Resources