Typeahead.js: problem with source async

Created on 26 Apr 2015  路  16Comments  路  Source: twitter/typeahead.js

$('#input-rms').typeahead({
  hint: true,
  highlight: true,
  minLength: 2,
  classNames: {
    menu: 'tt-dropdown-menu'
  }
},
{
  name: 'rms',
  limit: 10,
  source: function (q, sync, async) {
    $.ajax('/api/getrms?name='+q, // it will return a list of data of length 7
           {
            success: function(data, status){  async(data); }
           }
          );
  }
});

Problem:
The ajax url will return a list of data of length 7, however, the suggestions only render the first 3 results.

Can anyone gives a example about how to use the async in source.

customer support

Most helpful comment

Struggled with this problem for a long time today. Moving the line seems to fix it. How come it isn't being fixed in the release?

All 16 comments

Hmm, I'm not sure what's causing your problem. Here's an example I just whipped up that should be functionally equivalent to your code. It works as expected.

Can you test your code in an incognito window? Just to make sure there's nothing goofy going on with caching. Also, if you could point me towards a page that demonstrates your problem, I can help debug.

I tested in incognito window it doesn't work.

And I look at the source code of async function source code in typeahead.bundle.js.
In line 1705, rendered += suggestions.length is putted before that._append(query, suggestions.slice(0, that.limit - rendered));.

I think it is this line cause the problem. When I putted it after that._append(query, suggestions.slice(0, that.limit - rendered)); It works the way I want.

function async(suggestions) {
                    suggestions = suggestions || [];
                    if (!canceled && rendered < that.limit) {
                        that.cancel = $.noop;
                        rendered += suggestions.length;
                        that._append(query, suggestions.slice(0, that.limit - rendered));
                        that.async && that.trigger("asyncReceived", query);
                    }
                }

Yeah... I'm not sure why that line of code exists. I'll get it fixed, thanks for the report and thanks for digging into the problem. Very helpful.

Posted a PR with a fix, see #1200. Here's a version of _typeahead.bundle.js_ with the fix in case you want to try it out before it is released.

Ok, thanks

+1! The patch works like a charm! Can you please release it?

Release please!

Can confirm this is a problem. It's exacerbated when you only use async and your remote returns exactly limit results. In this case rendered - limit = 0, so (0,0) gets passed to suggestions.slice

For what it's worth, changing it this way makes async() structurally similar to sync(), and also keeps rendered updated correctly:

typeahead.bundle.js
1719聽聽聽聽function async(suggestions) {
1720聽聽聽聽聽聽聽聽suggestions =(suggestions || []).slice(0, that.limit - rendered);
1721聽聽聽聽聽聽聽聽if (!canceled && suggestions.length) {
1722聽聽聽聽聽聽聽聽聽聽聽聽that.cancel = $.noop;
1723聽聽聽聽聽聽聽聽聽聽聽聽rendered += suggestions.length;
1724聽聽聽聽聽聽聽聽聽聽聽聽that._append(query,suggestions);
1725聽聽聽聽聽聽聽聽聽聽聽聽that.async && that.trigger("asyncReceived", query);
1726聽聽聽聽聽聽聽聽}
1727聽聽聽聽}

Fixed by #1212

Is it just me who has a problem with this fix? Whenever rendered is smaller than limit, this is failing.
eg. rendered = 3; that.limit = 5

suggestions =(suggestions || []).slice(0, that.limit - rendered)
=> suggestions.length = 2

I don't know if I'm doing something wrong but for what it's worth, here's the work around I implemented:

function async(suggestions) {
    var howMany;
    suggestions = suggestions || [];
    if (!canceled && rendered < that.limit) {
       that.cancel = $.noop;
       rendered += suggestions.length;
       howMany = (rendered <= that.limit) ? rendered : that.limit - rendered;
       that._append(query, suggestions.slice(0, howMany));
       that.async && that.trigger("asyncReceived", query);
    }
}

@Sebsonic , I believe that's the intended behavior--limit is the total number of suggestions to render from all sources combined.

oh my god thank you guys so much for this fix. I was tearing my hairout with this one.

+1 I also am experiencing this problem, and had tracked down the problematic code. Great to see there's a fix!

+1 for pushing this fix. I also spent over an hour digging into the source of 0.11.1 and came to the same conclusion that the "rendered +=" line needs to be moved down.

Struggled with this problem for a long time today. Moving the line seems to fix it. How come it isn't being fixed in the release?

Was this page helpful?
0 / 5 - 0 ratings