Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tie Typeahead.js suggestions to a cross domain data source?

Title says it all.

I tried using a remote source, on the url (which is on another domain) and got back the following message:

XMLHttpRequest cannot load
http://www..../argument?callback=urlHandler. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:5000' is therefore not allowed
access.

Relevant Code

var films = new Bloodhound({
  datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.value); },
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {url: "http://www..../%QUERY?callback=urlHandler",
           ajax: $.ajax({type:'GET',dataType:'jsonp',jsonp:'jsonp'})                                    
  }
});

Update: It seems that the problem is with CORS issues. And the $.ajax settings object's dataType being set to jsonp is not respected. The comments below have more information.

EDIT: I found a fix! The question now becomes explaining why this worked.

So when I changed the url to http://www....?callback=? which actually made it load the response of the GET call as a JSONP object. Shouldn't the AJAX dataType and jsonp attributes have covered this?

like image 817
Louis93 Avatar asked Oct 01 '22 17:10

Louis93


1 Answers

This is kind of old but the method of accomplishing jsonp with Twitter Typeahead has changed since this question was asked and this answer comes up as one of the top results when searching for "twitter typeahead jsonp"

Any changes to the transport settings in typeahead should be done via the prepare function in the Bloodhound constructor.

var search = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.whitespace,
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            // `states` is an array of state names defined in "The Basics"
            //local: states,
            remote: {
                url: 'http://www.myserver.com/my_search_endpoint/SearchTerm=%searchValue',
                prepare: function(query, settings) {
                    settings.dataType = "jsonp"
                    settings.url = settings.url.replace('%searchValue', query)
                    return settings;
                }
            }
        });

the prepare function should return a settings object. See here for more details: https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md#remote

You will also need to make sure that you replace the wildcard value yourself in the prepare function.

             remote: {
                url: 'http://www.myserver.com/my_search_endpoint/SearchTerm=%searchValue',
                wildcard: '%searchValue'
             }

will no longer work once you specify prepare.

like image 121
Ryan Avatar answered Oct 05 '22 11:10

Ryan