question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

customized hit widget new transformItems not highlighting

See original GitHub issue

Do you want to request a feature or report a bug? Not sure.

What is the current behavior?

We have customized the hits widget with a transformItems function. The transformItems function splits our descriptionTruncated attribute on the first \n and displays the content above the split in one div (subhead) and the content after the split in a separate div (description) in our hits results template.

In our hits template, if we specify the attribute only within our div (ex: {{{subhead}}}) then it displays perfectly but, of course, we have not told it to highlight. We want it to highlight.

If we specify the highlight result, (ex: {{{_highlightResult.subhead.value}}} in the hits template, then those fields show up blank in our results.

We tried the helper using the v3 documentation and that also returned blank results (ex. {{#helpers.highlight}}{ “attribute”: “subhead” }{{/helpers.highlight}})

What is the expected behavior?

We expect to be able to highlight the hit result in the new transformed items we’ve created.

Here is the entire customized widget:

search.addWidget(
	 instantsearch.widgets.hits({
	   container: '#hits',
           transformItems(items) {
			return items.map(item => {
				var parseDescription = item.descriptionTruncated.split("\n");				
				var summary = parseDescription[0];
				var description = parseDescription[1];


				return {
                                   ...item,
                                   description: description,
                                   summary: summary
                                }
			});
	   },
	   templates: {
	     item: '<div class="hit">' +
	                       '    <div class="hit-content" style="padding-bottom: 2em;">' +
	                       '        <a href="{{{Url}}}" class="hit-name">{{{_highlightResult.title.value}}}<\/a>' +
	                       '        <div style="height:5px;"><\/div>' +
	                       '       <div class="hit-description" style="font-size: normal;"> <span style="font-weight: bold;">Inventors:</span> {{{finalPathInventors}}}<\/div>' +
	                       '       <div style="height:0px;"><\/div>' +
	                       '        <span class="hit-description" style="font-weight: bold;">Subhead:<\/span><span>{{{_highlightResult.subhead.value}}}<\/span>' +
						   '        <div style="height:5px;"><\/div>' +
						   '        <span class="hit-description" style="font-weight: bold;">Description: <\/span><span>{{{_highlightResult.description.value}}}<\/span>' +
	                       '        <div style="height:5px;"><\/div>' +
	                       '        <div class="hit-description" style="font-size: normal;"><span style="font-weight: bold;">Categories:<\/span> {{{finalPathCategories}}} <\/div>' +
	                       '        <div style="height:5px;"><\/div>' +
	                       '    <\/div>' +
	                       '<\/div>'
	                   },
	               })
	               );

And here is the orginal widget before customization, which, of course, highlights the descriptionTruncated just fine:

search.addWidget(
	 instantsearch.widgets.hits({
	   container: '#hits',
	   templates: {
	     item: '<div class="hit">' +
	                       '    <div class="hit-content" style="padding-bottom: 2em;">' +
	                       '        <a href="{{{Url}}}" class="hit-name">{{{_highlightResult.title.value}}}<\/a>' +
	                       '        <div style="height:5px;"><\/div>' +
	                       '       <div class="hit-description" style="font-size: normal;"> 
	                       '        <span class="hit-description" style="font-weight: bold;">Summary: <\/span><span>{{{_highlightResult.descriptionTruncated.value}}}<\/span>' +
	                       '        <div style="height:5px;"><\/div>' +
	                       '        <div class="hit-description" style="font-size: normal;"><span style="font-weight: bold;">Categories:<\/span> {{{finalPathCategories}}} <\/div>' +
	                       '        <div style="height:5px;"><\/div>' +
	                       '    <\/div>' +
	                       '<\/div>'
	                   },
	               })
	               );

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
benziocommented, Feb 21, 2019

The transformItems would look something like this:

    transformItems(items) {
      return items.map(item => {
        item._highlightResult.fakeName = {
          value: item._highlightResult['name'].value.toLocaleUpperCase(),
        };
        return item;
      });
    },

In this case my transform is making the value uppercase, I think in your case you want to trim, but I’m not fully sure from your code sample what the goal was.

Edit instantsearch.js-app

Thank you!

Yeah, we tried a whole bunch of different things, including the example above. I’ll try and be more clear of our goal: We had an attribute, descriptionTruncated, which the first string of text is the summary/subhead, then there is a line break (we had /n in the descriptionTruncated attribute in our json file) and then, following the line break is another string (the description). We wanted to display those two strings in separate divs in our hits template, and then have both of those separate divs highlighted when we typed in the search box.

We ended up using a Hogan helper. Anyway, it does what we need it to do. It displays the subhead in a separate div and then highlights the separate divs like it would with a normal widget.

hits({
  transformItems(items) {
    return items.map(item => {
      return {
        ...item,
        parseSummary: function() {
          return function(text) {
            return Hogan.compile(text)
              .render(this)
              .split("\n")[0];
          };
        },
        parseDescription: function() {
          return function(text) {
            var split = Hogan.compile(text)
              .render(this)
              .split("\n");
            return split[split.length - 1];
          };
        }
      };
    });
  },
  templates: {
    item:
      '<div class="hit">' +
      '    <div class="hit-content" style="padding-bottom: 2em;">' +
      '        <a href="{{{Url}}}" class="hit-name">{{{_highlightResult.title.value}}}</a>' +
      '        <div style="height:5px;"></div>' +
      '        <h1 class="hit-description" style="font-weight: bold; font-size: 1em;"></span><span>{{#parseSummary}}{{{_highlightResult.descriptionTruncated.value}}}{{/parseSummary}}</h1>' +
      '        <div style="height:5px;"></div>' +
      '        <div class="hit-description" style="color: #505050;"><span style="font-weight: bold; color: #000;">Summary: </span><span>{{#parseDescription}}{{{_highlightResult.descriptionTruncated.value}}}{{/parseDescription}}</span>' +
      '        <div style="height:5px;"></div>' +
      '        <div class="hit-description" style="font-size: normal; color: #505050;"><span style="font-weight: bold; color: #000;">Categories:</span> {{{finalPathCategories}}} </div>' +
      '        <div style="height:5px;"></div>' +
      "    </div>" +
      "</div>"
  }
});

Extraneous info…the syntax was important in the hits template because, at first, we only had two brackets around our highlightResults so it was highlighting but stripping the highlight style (It was putting mark tags around the highlighted values. Once we put the extra bracket around the highlightResults, the expected styling came back.

1reaction
benziocommented, Feb 19, 2019

If I understand your question correctly, you are creating a new key within the “hit” object and want to use that for highlighting. However, the highlighting happens in the Algolia engine, and not frontend.

To have a highlighted value, you’ll need to set _highlightResults[yourNewKey].value = transformOrSomething(_highlightResults[yourOldKey].value).

Hope that makes sense!

Thank you so much for your response. Really appreciate it.

In transformItems we are not able to access the _highlightResults.

Where should we put _highlightResults[yourNewKey].value = transformOrSomething(_highlightResults[yourOldKey].value)?

Read more comments on GitHub >

github_iconTop Results From Across the Web

hits | InstantSearch.js - Algolia
If you're transforming an attribute using the highlight widget, you need to transform item._highlightResult[attribute].value . Copy. 1 2 ...
Read more >
Instant Meilisearch - npm
The configure widget lets you provide raw search parameters to the Algolia API without rendering anything. Because these are the search ...
Read more >
How to use react router with Algolia search hits?
It looks like you're using a custom Hits widget here rather than the out-of-the-box instantsearch.js widget (which is fine).
Read more >
How to Set up an Algolia Instasearch App on your Strattic Site
If that's the case, you can use this method: https://www.algolia.com/doc/api-reference/widgets/hits/js/#widget-param-transformitems (see below code for more ...
Read more >
Implementing Filter and the Clear Filter Component
These facets will be used as a way to filter the hits. ... which is about whether the button should clear the search...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found