I'm using latest version of typeahead.js (v0.11.1). I observed strange behaviors when using different ids for dataset values.
I've created a JSFiddle. Here's the js code:
var ds = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: [{id: 1, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 3, name: "a"}],
identify: function(obj) { return obj.id; }
});
$('#go').typeahead(null, {
name: 'ds',
display: 'name',
source: ds
});
Now typeahead may malfunction if I change the data for 'local'. Here are just some examples:
Using one of these values for 'local' (notice the third element are random numbers starting with '1'):
[{id: 1, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 15, name: "a"}]
[{id: 1, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 1849, name: "a"}]
Now when I enter into text box: "a b", typeahead is expected to suggest "a b 1" and "a b 2", but in fact it only suggests "a b 1".
This can be fixed by one of these:
Change 'id' property of third element to a value that doesn't start with '1'. Example:
[{id: 1, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 23, name: "a"}]
Change 'name' property of third element to a value that doesn't start with 'a'. Example:
[{id: 1, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 15, name: "s"}]
Remove 'identify' property of Bloodhound constructor object.
What's more, if I use a number greater than 2 as id of first element, like this:
[{id: 3, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 15, name: "a"}]
Now when I enter "a b" into text box, there's no suggestion!
Answering my own question. Yes there is a bug in bloodhound. SearchIndex.getIntersection() function is incorrectly implemented. You can take out this function and test it like this:
It is supposed to return [1,2] as result, but in fact it returns [1]. This is because it uses sort() function incorrectly to sort numbers. According to w3schools:
So this function can be fixed by changing these two lines:
into:
Took me 1 day to find out :(