Skip to content Skip to sidebar Skip to footer

Is There Any Method To Iterate A Map With Handlebars.js?

It is easy to iterate an array with Handlebars.js like: {{#each comments}}

{{title}}

{{{{url}}}
{{/each}} and an

Solution 1:

This is now supported with:

{{#each headers}}
    Key: {{@key}}, Value: {{this}}
{{/each}}

Solution 2:

The answer above is in the right track, this is my refinement:

Handlebars.registerHelper( 'eachInMap', function ( map, block ) {
   var out = '';
   Object.keys( map ).map(function( prop ) {
      out += block.fn( {key: prop, value: map[ prop ]} );
   });
   return out;
} );

And to use it:

{{#eachInMap myMap}}key:{{key}}value: {{value}}
{{/eachInMap}}

Solution 3:

Recent versions of Handlebars.js support a more readable iteration format (see here):

{{#each object as |value key|}}
    {{key}} => {{value}}
{{/each}}

In my opinion this is less surprising than introducing the @key syntax as suggested by Tasos Zervos' answer.

Solution 4:

all you have to do is register a helper like so:

Handlebars.registerHelper( 'eachInMap', function ( map, block ) {
   Object.keys( myObj ).map(function( prop ) {
       returnblock( myObj[ prop ] );
   });
} );

in your template you can call that:

{{#eachInMap mapObject}}
some HTML and other stuff
{{/eachInMap}}

that's it. Hope it is of any use

Solution 5:

A more complete example for use with Map() - with supporting functions taken from handlebars - which will allow block vars inside the eachOfMap to work.

    function appendContextPath(contextPath, id) {
      return (contextPath ? contextPath + '.' : '') + id;
    }

    function blockParams(params, ids) {
      params.path = ids;
      return params;
    }

    Handlebars.registerHelper('eachOfMap', function (map, options) {
      let contextPath;
      if (options.data && options.ids) {
        contextPath = appendContextPath(options.data.contextPath, options.ids[0]) + '.';
      }

      let data = Handlebars.createFrame(options.data);

      varout = '';
      for (let [key, item] of map) {
        data.key = key;
        if (contextPath) {
          data.contextPath = contextPath+key;
        }
        // out += block.fn({"key": key, "value": item});out = out + options.fn(item, {
          data: item,
          blockParams: blockParams([item, key], [contextPath + key, null])
        });
      }
      returnout;
    })

Usage:

let dataAsMap = new Map([["keyOne", {name: "bob", age: 99}], ["keyTwo", {name: "alice", age: 99}]]);

    {{#eachOfMap (dataAsMap)}}
      <li>
        {{> "fragments/childTemplate"}}
      </li>
    {{/eachInMap}}

    <span>Hey {{name}}, you're {{age}} years </span>

Post a Comment for "Is There Any Method To Iterate A Map With Handlebars.js?"