Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added local variables on render #4429

Open
JStyle21 opened this issue Oct 10, 2020 · 3 comments
Open

Added local variables on render #4429

JStyle21 opened this issue Oct 10, 2020 · 3 comments

Comments

@JStyle21
Copy link

@JStyle21 JStyle21 commented Oct 10, 2020

Hi,

I'm using express and ejs.
I passed an object to res.render then called a for in loop on it on the template but when it's printed it has _locals inside too.
Everywhere i checked inside the object it wasn't there, yet on output to the end user it has this extra variable.
I didn't find anything directly on this but a couple of other issues kinda point out that local variables are automatically included in the response to the view and yet i have never encountered this situation before.

I had to do a hacky solution for this with an if statement checking for this and ignoring it.

Any other comments on this?

@dougwilson
Copy link
Member

@dougwilson dougwilson commented Oct 10, 2020

There is nothing in express that is adding something called _locals that I am aware of. Can you provide a reproducible example of the issue you are having? Does it happen with all template engines or only ejs?

@JStyle21
Copy link
Author

@JStyle21 JStyle21 commented Oct 10, 2020

That was a fast reply and an unexpected answer.
Sure i"l try to provide anything i can.
No i haven't used or tried anything but EJS.

Here is the code:

groupby(Function)

const groupBy = function (xs, key) {
    return xs.reduce(function (rv, x) {
        (rv[x[key]] = rv[x[key]] || []).push(x);
        return rv;
    }, {});
};

Route

app.get('/test', async (req, res) => {
t = await db.getQuestions(1);
zz = groupBy(t, 'question');
res.render('pages/test', zz);
});

View(EJS):

<% for( const property in zz ) { %>
<p><%= property %></p>
<% } %> 

As far as the Data, this is how it looks like after each step:

From DB

[
  {
    question_id: 1,
    question: 'Lorem ipsum dolor sit amet',
    answer: 'Lorem',
    value: 1
  },
  {
    question_id: 1,
    question: 'Lorem ipsum dolor sit amet',
    answer: 'ipsum',
    value: 3
  },
  {
    question_id: 1,
    question: 'Lorem ipsum dolor sit amet',
    answer: 'dolor',
    value: 5
  },
]

After groupBy:

{
  'Lorem ipsum dolor sit amet': [
    {
      question_id: 1,
      question: 'Lorem ipsum dolor sit amet',
      answer: 'Lorem',
      value: 1
    },
    {
      question_id: 1,
      question: 'Lorem ipsum dolor sit amet',
      answer: 'ipsum',
      value: 3
    },
    {
      question_id: 1,
      question: 'Lorem ipsum dolor sit amet',
      answer: 'dolor',
      value: 5
    }
  ],
}

In the FE:

<p>Lorem ipsum dolor sit amet</p>
            
<p>_locals</p>
@JStyle21
Copy link
Author

@JStyle21 JStyle21 commented Oct 11, 2020

BTW if i stringify the object on render
res.render('pages/test', JSON.stringify(zz));

I get the following error:
(node:337233) UnhandledPromiseRejectionWarning: TypeError: Cannot create property '_locals' on string

So i'm thinking render adds that property on any object it sends.

Update:
Just tried putting that object in an object when rendering and that made the problem go away
res.render('pages/test', {zz});

Very strange but somehow related to passing an object directly to render rather than inside an object.
Never had a problem before...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.