简体   繁体   中英

Server side rendering json data using NodeJS, Express, Handlebars and expbhs

So I was having trouble server side rendering some JSON data using ExpressJS and Handlebars and also using the expbhs view engine. Given the following:

obj:

[
 {
  prop1: 'value',
  prop2: 'value',
  prop3: 'value',
  prop4: 'value'
 },
  prop1: 'value',
  prop2: 'value',
  prop3: 'value',
  prop4: 'value'
 }
]

Controller:

exports.displayData = (req, res) => {

    //assume valid json
    res.render('myTemplate', {
        obj
    });
}

My handlebars template (myTemplate.hbs) looks something like this:

{{#each this}}
    <div class='section'>
        <div id="{{prop1}}-section" >
            <div>
                <img src='{{prop2}}'>
            </div>

            <div>
                <div class=''>
                    stuff{{prop3}}
                </div>

                <div>
                    other stuff: {{prop4}}
                </div>

                </div>
                <div>
                    Data for: {{prop1}}
                </div>
            </div>
        </div>
    </div>
{{/each}}

This will render the template but no property values will be populated.

I realized I was wrapping my obj in another obj in my res.render() call, so I changed the call to:

exports.displayData = (req, res) => {

    //assume valid json
    res.render('myTemplate', obj);
}

This partially solved the answer. I was getting all the obj data populated, but it was also rendering extra .section <div> s with empty property values.

So I tried the following:

In my controller, I changed the res.render() json parameter to { data: obj } like so:

exports.displayData = (req, res) => {

    //assume valid json
    res.render('myTemplate', { data: obj });
}

and in my template I changed my #each block from this to data like so:

{{#each data}}
    <div class='section'>
        <div id="{{prop1}}-section" >
            <div>
                <img src='{{prop2}}'>
            </div>

            <div>
                <div class=''>
                    stuff{{prop3}}
                </div>

                <div>
                    other stuff: {{prop4}}
                </div>

                </div>
                <div>
                    Data for: {{prop1}}
                </div>
            </div>
        </div>
    </div>
{{/each}}

My guess is that either exphbs or handlebars adds properties to the obj by default and those properties were being passed in this when it was rendering the document. That would explain the empty <div> s

I figured this out because I was planning on swapping my layout to something else for that particular render, and to do that it would have looked like this:

exports.displayData = (req, res) => {

    //assume valid json
    res.render('myTemplate', { 
        data: obj,
        layout: 'nonDefault'
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM