Search code examples
jqueryajaxgettypeahead.jsbloodhound

How to send data in request body when using Typeahead & Bloodhound?


I'm trying to implement a typeahead whose source is an API that expects a GET request with a body of data, not url encoded data. I've tried a few different things in the 'prepare' object, but can't get it to url encode parameters. Is it possible with typeahead, or jquery in general, to have it not do this? I have a feeling jquery maybe just doesn't let you do this, since it would be considered 'bad practice', but changing the API is not really an option! Here is my code:

$(document).ready(function(){
  var people = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: {
    url: 'apiUrl',
    prepare: function (query, settings) {
                      settings.type = "GET";
                      settings.contentType = "application/json";
                      settings.DataType = "json";
                      settings.processData = false;
                      settings.data = JSON.stringify({"search":"people","query":query});
                      return settings;
                   }
    }
  });
  $('.typeahead').typeahead(null, {
    source: people
  });
})

I'm using jquery 1.11.3 & typeahead.js 0.11.1.

Thanks!


Solution

  • Try using minimally modified version of typeahead.js substringMatcher function , .on() , input event

    var substringMatcher = function(strs, q, cb) {
      return (function(q, cb, name) {
        var matches, substrRegex;
        // an array that will be populated with substring matches
        matches = [];
        // regex used to determine if a string contains the substring `q`
        substrRegex = new RegExp(q, 'i');
        // iterate through the pool of strings and for any string that
        // contains the substring `q`, add it to the `matches` array
        $.each(strs, function(i, str) {
          if (substrRegex.test(str)) {
            // the typeahead jQuery plugin expects suggestions to a
            // JavaScript object, refer to typeahead docs for more info
            matches.push(name(str));
          }
        });
        cb(matches);
      }(q, cb, function(res) {
        return res
      }));
    };
    
    
    $("#typeahead").on("input", function(e) {
      $.ajax({
          url: "https://gist.githubusercontent.com/guest271314/"
               + "ffac94353ab16f42160e/raw/"
               + "aaee70a3e351f6c7bc00178eabb5970a02df87e9/states.json",
          processData:false,
          data: JSON.stringify({
            "search": "people",
            "query": e.target.value
          })
        })
        .then(function(json) {
          if (e.target.value.length) {
            substringMatcher(JSON.parse(json), e.target.value, function(results) {
              $("#results ul").empty();
              $.map(results, function(value, index) {
                $("#results ul")
                .append($("<li />", {
                  "class": "results-" + index,
                  "html": value
                }))
              })
            })
          } else {
            $("#results ul").empty();
          }
        }, function err(jqxhr, textStatus, errorThrown) {
          console.log(textStatus, errorThrown)
        })
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
    </script>
    <input type="text" id="typeahead" placeholder="search" />
    <br />
    <div id="results">
      <ul>
      </ul>
    </div>