Will Taylor
Will Taylor

Reputation: 2304

Twitter typeahead only showing some items returned by bloodhound

I'm using Bloodhound to fetch data from the database, then twitter typeahead to display the options below a search box.

Currently, the bloodhound part is finding the objects required, but the typeahead is not displaying them.

 var artist_retriever = new Bloodhound({
    // turns input query into string of tokens to send to database.
    queryTokenizer: Bloodhound.tokenizers.whitespace,

    remote: {
              // URL to fetch information from
              url: "/artists?query=%QUERY",
              wildcard: '%QUERY',
              // Manipulate the array of artists returned, for display to user.
              transform: function(array_of_artists){
                            // array of artists is returned from DB.
                            // Put each artist into a readable string
                            array_of_artists = create_artist_descriptions(array_of_artists)

                            console.log(array_of_artists)
                            // Returns correctly:
                            // [
                            //   { artist: "Joe" },
                            //   { artist: "Bob" },
                            //   { artist: "Smith" },
                            //   { artist: "Tom" },
                            // ]

                            return array_of_artists
                          }
            },

    // turns return value into a string of results, with this 'key' before each result.
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('artist'), 


  });

// display:



// instantiate the typeahead UI
  // https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md
  searcher = $('.typeahead').typeahead(
    // options:
    {
      hint: false
    },
    // datasets:
    {
      // Where to get data: User the bloodhound suggestion engine:
      source: artist_retriever.ttAdapter(),
      // Which attribute of each result from the database should be shown:
      displayKey: 'artist',
      templates: {
                    notFound: new_artist_option_template(),
                    footer: new_artist_option_template()
                 }
    }
  )

Update

It turns out that there's a weird bug in typeahead. It only seems to work with the "limit" attribute set to a maximum of 4. If you set "limit" to 5, the typeahead gives you nothing.

searcher = $('.typeahead').typeahead(
    // options:
    {
      hint: false
    },
    // datasets:
    {
      // Where to get data: User the bloodhound suggestion engine:
      source: artist_retriever.ttAdapter(),
      // Which attribute of each result from the database should be shown:
      displayKey: 'signature',
      limit: 4, // This can do a max of 4! Odd.
      templates: {
                    notFound: new_artist_option_template(),
                    footer: new_artist_option_template()
                 }
    }

Upvotes: 5

Views: 1392

Answers (1)

Rash
Rash

Reputation: 8197

This issue has been solved. Please see update 2 directly.

I have reproduced this issue in this JSFIDDLE.

As you said, its a bug. You also reported that this bug goes away if you do limit:4.

Actually on my end, or in the FIDDLE, I have experienced that this issue comes when the number of results returned = value in limit.

To test this issue in the FIDDLE, do the following: Note: Searching for 1947 returns exactly 5 rows.

When limit is set to 4: Searching for 1947 returns 4 results.

When limit is set to 5: Searching for 1947 returns nothing.

When limit is set to 6: Searching for 1947 returns one 1 result - the first result.


Hence if you keep the limit set to 1 less than the actual number of results returned, then this will keep on working.

I have also submitted this issue in their github page. I will be keeping track of this issue and will keep updating this answer as need be.

Update 1:

Found a similar question on SO here. "Luciano García Bes" seems to have figured the solution. Please direct all upvotes there.

Basically he says:

It's counting the number of rendered hints before appending them, so if the number of hints equals the limit it'll append an empty array.

To prevent this I just switched lines 1723 and 1724 so it looks like this:

that._append(query, suggestions.slice(0, that.limit - rendered));
rendered += suggestions.length;

Update 2:

This issue has been fixed on pull 1212. Closing our own issue 1312. The bug was corrected the same way discussed in update 1.

Upvotes: 3

Related Questions