Why does looping through a mongoose object with nunjucks display metadata?
I am using mongodb and nunjucks in an app I am writing.
I am trying to iterate through a model called persona
, but doing so displays mongoose metadata associated with the record.
If I simply display the persona
variable by writing {{persona}}
.
My output is as follows. Just the keys/values defined in my schema.
{ _id: 582f186df1f05603132090d5, name: 'Alex', name_lower: 'alex', __v: 0,
meta: { validated: null, contributors: 'Research Team', sources: '4 Interviews' },
pain_points: { points: 'Debugging' },
ideal_day: { responsibilities: 'Coding websites.', goals: 'Finish the research site.', joys: 'Good code, Good food.', hobbies: 'Dance, Hiking, Eating' },
environment: { workspace: 'Desk', tools: 'Atom, Sketch', info_from: null, info_to: null, coworkers_relationship: null, technology_relationship: null },
basic_info: { jobtitle: 'FED', experience: '2', education: 'CS', company: '' } }
However, if I loop through the persona
{% for name, item in persona %} {{ name }} : {{ item }} {% endfor %}
In addition to displaying the keys in my schema, all mongoose metadata associated with the record will also be displayed. I would like to understand why different information is displayed when I am looping over the object.
$__ isNew errors _doc $__original_save save _pres _posts $__original_validate validate $__original_remove remove db discriminators __v id _id meta pain_points ideal_day environment basic_info updated_at created_at name_lower name schema collection $__handleSave $__save $__delta $__version increment $__where
I was able to fix this problem by using Mongoose's lean()
, but still don't understand why I experienced this behavior.
When you call {{persona}}
then result is persona.toString()
.
If object doesn't have override method toString
then result will be [Object object]
(by default toString
method).
When you use loop {% for key, value in persona %}
then it's equals to
for(var key in obj)
print(key + ' - ' + obj[key]);
This code prints all object properties and methods.
To exclude methods you must use next loop
for(var key in obj)
if (typeof(obj) != 'function') // or obj.hasOwnProperty(key)
print(key + ' ' + obj[key]);
So, to avoid your problem you must "clear" data before pass it to nunjucks or before output.
You can do it define custom filter
var env = nunjucks.configure(...
env.addFilter('lean', function(obj) {
var res = {};
for(var key in obj)
if (typeof(obj) != 'function') // or obj.hasOwnProperty(key)
res[key] = obj[key];
return res;
});
...
{% for key, value in persona | lean %}
{{key}} - {{value}}
{% endfor %}