JavaScript Express Basics Using Templates with Express Review Response.render

nico dev
nico dev
20,360 Points

res.render('view',[locals]) : Not fully understanding why the string as the key and the variable as the value?

Hello community,

After many attempts, I could finally pass this challenge, but I am not happy because I don't understand why I did it the way I did :)

Now, I guess the challenge will probably linked in the top right corner of the page, but just in case, to give some context, this is the file:

const express = require('express');
const posts = require('./mock/posts.json');

const app = express();

app.set('view engine', 'pug');
app.set('views', __dirname + '/templates')

app.get('/', (req, res) => {
  res.render('main');
});

app.listen(3000, () => {
  console.log("The frontend server is running on port 3000!");
});

I am now being required to:

Pass the posts object to your template, naming it "posts".

I might not have yet understood this fully, I think, but I was trying to pass it as an object with the variable posts as the property/key and the string 'posts' as its respective value.

That's how we did it so far in this course, but it's also how you can find it in Express docs, here.

However, that seems wrong, giving me the message:

The second argument to render() needs to have the 'posts' variable as the value of its 'posts' attribute.

I know this might sound like a trivial question to someone experienced with Node and Express, but just simply: why?

I understand they expect me to pass the variable as the value, and the string as the property, but I can't get to see why is that way? Maybe I'm too used to assign values the other way around.

Looking forward to any suggestion, idea, advice, correction, and insight. Thank you so much in advance!

1 Answer

There is nothing different here than the usual way you are used to. The reason why you see a string in the express documentation is that they are hardcoding the value 'Topi' as the name property. So when someone visits that page. name will always be 'Tobi'. However, in your case you do not want to pass a string to the template. Instead, you want to pass an object with several properties. That way you can access those properties in the template.

res.render('main', {name: 'Tobi'});  //name will always be tobi

So in your template - name will always turn out to be tobi

h1 {{name}}
p Hello my name is {{name}}

But when using an object you are a lot more flexible in your template

postsObject = {
     posts: [
              {name: "Post 1", owner: "Alex", content: "Bla bla bla"},
              {name: "Post 2", owner: "Tobi", content: "Some content again"}
     ]
}

//now we can pass that postsObject into our template
res.render('main', {posts: postsObject});

Now in the template we are a lot more flexible

h1 {{posts.posts[0].name}}
h3 {{posts.posts[0].owner}}
p {{posts.posts[0].content}}

In the future obviously you will get that postsObject from a database somewhere. :)

nico dev
nico dev
20,360 Points

Thank you so much, Alexander La Bianca , for taking the time to give me such a clear answer. And I fully agree with you. I would swear, though, that the other day, I tried to do:

res.render('main', {posts: posts})

... and it hand't worked, until I did:

res.render('main', {'posts': posts})

which honestly didn't (and still doesn't) make any sense to me (?).

However, I am more awake, fresh-minded now I guess, cause I tried the same thing and it worked now... ha ha, does coding burnout exist? Maybe I had an episode :)

Thank you so much!!