InstantSearch return an unique allItems template at runtime

Is it possible to show different “hits” templates based upon the items that’s being returned from the API? For instance, let’s say that I have two templates.

const _FooTemplate = `
    <table class="table table-striped table-hover table-responsive">
      <thead>
        <tr>
          <th>Part Number</th>
          <th>Description</th>
          <th>Available Quantity</th>
        </tr>
      </thead>
      <tbody>
      {{#hits}}
        <tr>
          <td style="white-space:nowrap"><a href="{{ url }}">{{ code }}</a></td>
          <td>{{ description }}</td>
          <td>{{ quantityAvailable }}</td>
        </tr>
      {{/hits}}
      </tbody>
    </table>
  `;

const _BarTemplate = `
    <table class="table table-striped table-hover table-responsive">
      <thead>
        <tr>
          <th>Part Number</th>
          <th>Description</th>
          <th>Available Quantity</th>
          <th>EXTRA COLUMN - 1</th>
          <th>EXTRA COLUMN - 2</th>
        </tr>
      </thead>
      <tbody>
      {{#hits}}
        <tr>
          <td style="white-space:nowrap"><a href="https://www.lyntron.com/{{ url }}">{{ code }}</a></td>
          <td>{{ description }}</td>
          <td>{{ quantityAvailable }}</td>
          <td>{{ EXTRA_DATA_1 }}</td>
          <td>{{ EXTRA_DATA_2 }}</td>
        </tr>
      {{/hits}}
      </tbody>
    </table>
  `;

And my search widget looks like this…

    search.addWidget(
        instantsearch.widgets.hits({
            container: '#hits',
            templates: {
                empty: 'No results',
                allItems: (function($hitsObject) {
                    return templateFactory($hitsObject);
                })
            },
            cssClasses: {
                item: 'col-lg-12 col-md-12 col-sm-12'
            }
        })
    );

My template factory has the logic to determine if I’m pulling out _FooTemplate or _BarTemplate.

function templateFactory($hits) {
    //Logic to determine which template to return.  For now hardcode one.

    return _FooTemplate;
}

When I use this approach my hits div on the HTML side being escaped and not rendering correction. How can I get the rendering to happen? Am I escaping the HTML somewhere and I shouldn’t be?

Currently getting this for a result…

And I desire this for a result. Properly rendered.
26 PM

So what you are running into is the difference between a string template and a html template. A string template will be using Hogan.js templates (the syntax you used). A function template will be done using innerHTML.

This has the main difference that you would receive all information you need in the argument to the function, and can pass that to your template:

templates: {
  item: function({things}) {
    return `<div> ${things.map((thing) => `<p>${thing.name}</p>`)`</div>`;
  }
}

Basically this will put all logic in js again, instead of the templating language.

While InstantSearch.js doesn’t directly expose Hogan, it should be possible to reuse it probably, but that depends on the way you’re importing InstantSearch, is that with npm, jsdelivr or something else?