typeahead.js prefetch problems

rusty1042 picture rusty1042 · Sep 6, 2013 · Viewed 10.6k times · Source

I'm using a typeahead.js on a Google App Engine project and having problems using prefetch.

The typeahead works fine when I use local but if I copy the same dataset to a json file and use prefetch, the typeahead does not work, i.e. no suggestions are displayed.

Here's my version of the code using local:

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Demo</title>
</head>
<body>
    <div><input type="text" name="typeahead-example" placeholder="Type here" class="typeahead-example"></div>
    <script src="./js/jquery-1.10.2.js" type="text/javascript"></script>
    <script src="./js/hogan.js" type="text/javascript"></script>
    <script src="./js/typeahead.min.js" type="text/javascript"></script>
    <script>
        $(document).ready(function(){
                $('input.typeahead-example').typeahead({
                  name: 'example',
                  local: [{value: 'Abc Def', tokens: ['Abc', 'Def'], name: 'random1', val2: 'A', val3: 'B'},
                    {value: 'Def Ghi', tokens: ['Def', 'Ghi'], name: 'random2', val2: 'C', val3: 'D'},
                    {value: 'Ghi Jkl', tokens: ['Ghi', 'Jkl'], name: 'random3', val2: 'E', val3: 'F'},
                    {value: 'Jkl Mno', tokens: ['Jkl', 'Mno'], name: 'random4', val2: 'G', val3: 'H'}],
                  limit: 3,
                  valueKey: 'name',
                  template: '<p>{{value}}</p>',
                  engine: Hogan
                });
            });
    </script>
</body>
</html>

Here's my version of the code using prefetch:

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Demo</title>
</head>
<body>
    <div><input type="text" name="typeahead-example" placeholder="Type here" class="typeahead-example"></div>
    <script src="./js/jquery-1.10.2.js" type="text/javascript"></script>
    <script src="./js/hogan.js" type="text/javascript"></script>
    <script src="./js/typeahead.min.js" type="text/javascript"></script>
    <script>
        $(document).ready(function(){
                $('input.typeahead-example').typeahead({
                  name: 'example',
                  prefetch: {url: './json/example.json', ttl: '0'},
                  limit: 3,
                  valueKey: 'name',
                  template: '<p>{{value}}</p>',
                  engine: Hogan
                });
            });
    </script>
</body>
</html>

Here's the example.json file:

[{value: 'Abc Def', tokens: ['Abc', 'Def'], name: 'random1', val2: 'A', val3: 'B'}, {value: 'Def Ghi', tokens: ['Def', 'Ghi'], name: 'random2', val2: 'C', val3: 'D'}, {value: 'Ghi Jkl', tokens: ['Ghi', 'Jkl'], name: 'random3', val2: 'E', val3: 'F'}, {value: 'Jkl Mno', tokens: ['Jkl', 'Mno'], name: 'random4', val2: 'G', val3: 'H'}]

The problem occurs in Chrome and Firefox. Debugging in chrome, I can see that the example.json file is served and received. The preview and response of the network activity for example.json shows the contents of the file in its entirety. However, on the resources section of the chrome debugger, Local Storage is empty. There are no console errors, just this message

XHR finished loading: "http://localhost:8000/json/example.json". jquery-1.10.2.js:8706
send jquery-1.10.2.js:8706
jQuery.extend.ajax jquery-1.10.2.js:8136
jQuery.(anonymous function) jquery-1.10.2.js:8282
jQuery.extend.getJSON jquery-1.10.2.js:8265
c.mixin._loadPrefetchData typeahead.min.js:7
proxy jquery-1.10.2.js:827
c.mixin.initialize typeahead.min.js:7
proxy jquery-1.10.2.js:827
(anonymous function) typeahead.min.js:7
jQuery.extend.map jquery-1.10.2.js:782
g typeahead.min.js:7
jQuery.extend.each jquery-1.10.2.js:657
jQuery.fn.jQuery.each jquery-1.10.2.js:266
b.initialize typeahead.min.js:7
jQuery.fn.typeahead typeahead.min.js:7
(anonymous function) prefetch.html:14
fire jquery-1.10.2.js:3048
self.fireWith jquery-1.10.2.js:3160
jQuery.extend.ready jquery-1.10.2.js:433
completed

With respect to this post, I'm not having cross domain issues and with respect to this post, I've set ttl to 0 and the problem still persists.

Any help would be appreciated.

  • UPDATE * In response to suggestion from @NitzanShaked I added some console logging.

First I tried this and nothing registered in the console.

$(document).ready(function(){
    $('input.typeahead-example').typeahead({
      name: 'example',
      prefetch: {
        url: './json/example.json', 
        ttl: '0',
        filter: function (data) {
            console.log(data);
            for (var i = 0; i < data.length; i++) {
                datum = data[i];
                console.log(datum);
            }
            return data;
        }
      },
      limit: 3,
      valueKey: 'name',
      template: '<p>{{value}}</p>',
      engine: Hogan,
    });
});

Then I tried this:

$(document).ready(function(){
    $('input.typeahead-example').typeahead({
      name: 'example',
      prefetch: {url: './json/example.json', ttl: '0'},
      limit: 3,
      valueKey: 'name',
      template: '<p>{{value}}</p>',
      engine: Hogan,
    }).bind('typeahead:opened', function (obj, datum) {
                console.log(obj);
                console.log(datum);
                console.log(datum.val2);
                });
});

Which caused the console to log the following when I click inside the input field

jQuery.Event {type: "typeahead:opened", timeStamp: 1378502920480, jQuery1102039872112357988954: true, isTrigger: 3, namespace: ""…}
currentTarget: input.typeahead-example tt-query
data: null
delegateTarget: input.typeahead-example tt-query
handleObj: Object
isTrigger: 3
jQuery1102039872112357988954: true
namespace: ""
namespace_re: null
result: undefined
target: input.typeahead-example tt-query
timeStamp: 1378502920480
type: "typeahead:opened"
__proto__: Object
 prefetch.html:22
undefined prefetch.html:23
Uncaught TypeError: Cannot read property 'val2' of undefined prefetch.html:24
(anonymous function) prefetch.html:24
jQuery.event.dispatch jquery-1.10.2.js:5095
elemData.handle jquery-1.10.2.js:4766
jQuery.event.trigger jquery-1.10.2.js:5007
(anonymous function) jquery-1.10.2.js:5691
jQuery.extend.each jquery-1.10.2.js:657
jQuery.fn.jQuery.each jquery-1.10.2.js:266
jQuery.fn.extend.trigger jquery-1.10.2.js:5690
c.mixin.trigger typeahead.min.js:7
c.mixin._propagateEvent typeahead.min.js:7
proxy jquery-1.10.2.js:827
d.trigger typeahead.min.js:7
proxy jquery-1.10.2.js:827
c.mixin.open typeahead.min.js:7
proxy jquery-1.10.2.js:827
c.mixin._openDropdown typeahead.min.js:7
proxy jquery-1.10.2.js:827
d.trigger typeahead.min.js:7
proxy jquery-1.10.2.js:827
c.mixin._handleFocus typeahead.min.js:7
proxy jquery-1.10.2.js:827
jQuery.event.dispatch jquery-1.10.2.js:5095
elemData.handle

Answer

Nitzan Shaked picture Nitzan Shaked · Sep 7, 2013

Your problem is in example.json, as it turns out... You need to quote key names using double quotes, and all strings (e.g. in tokens) need to be quoted in double quotes as well.

For example, this works for me:

[{"value": "Abc Def", "tokens": ["Abc", "Def"], "name": "random1", "val2": "A", "val3": "B"}]

It would also be wise to change the url from ./json/example.json to /json/example.json (remove the leading dot).