简体   繁体   中英

How to handle properly an ajax request

I was curious about how to get autocomplete working in my test application I am developing with Laravel 4, just for practise. So I just googled it and found this library , with jQuery as its only dependency.

I am not an expert of JavaScript and jQuery and I don't know anything about AJAX, I just did what the manual said and with a bit of common sense figured how it worked overall.

Here's the JavaScript code that applies the autocomplete operation:

$('#autocomplete').autocomplete({
    serviceUrl: '/search',
    onSelect: function(suggestion) {
        $('#autocomplete-suggestions').html("<a href='users/" + suggestion.data + "'>" + suggestion.value + "</a>");
    }
})

I defined the services in the routes.php file, since it's very short:

Route::get('search', function() {
    $users = User::all();
    $response = array(
        "suggestions" => array()
    );
    foreach ($users as $user) {
        array_push($response["suggestions"], array("value" => $user->username, "data" => $user->id));
    }

    return Response::json($response);
});

The way this works got me wondering. I mean, every time the user types a character in the input box a request is made and the service is executed, which is in the routes method. This implies retrieving all the users from the database, storing them in an array and then copying it all again to a new array so it adjusts to the expected input. And then, on that json the actual search is made.

This seem very inefficient to me, since this operation has a cost and it is performed with great frequency. It would be way better if the search was made as a query against the database, instead of an object product to a couple of copies of (potentially) a lot of data.

Also, I seeded some new users with this piece of code:

for ($i = 0; $i<1000; $i++) {
    $user = new User;
    $user->username = 'username' . $i;
    // assign the rest of the attributes
    $user->save();
}

And it seemed like the search wasn't made properly. I guess this is a different issue, concerning the autocomplete library itself.

So, since I am not familiar with AJAX, I just want to know if this is the usual way to operate, or if this is indeed a terrible idea as I think. What would be the proper way to do it?

Should I be returning all users with each request and searching on the client side?

Absolutely not. When the request is made to your server via AJAX, the search query is supplied as a query string parameter. From their docs:

Web page that provides data for Ajax Autocomplete, in our case autocomplete.ashx will receive GET request with querystring ?query=Li, and it must return JSON data in the following format

You can get that from Laravel: $query = \\Input::get('query');

You should be using that string to search on your users table using eloquent or whatever and returning only matching suggestions.

Is it terrible to make a HTTP request with every keystroke?

That library has an option called deferRequestBy . When given an integer value (milliseconds), it will wait this long until executing the request on a keyUp event. If another keyUp event comes in, it will cancel the first. This helps to reduce the number of concurrent requests you may be running.

https://github.com/devbridge/jQuery-Autocomplete/blob/master/src/jquery.autocomplete.js#L384-L384

Directly from their Readme on Github :

deferRequestBy : Number of miliseconds to defer ajax request. Default: 0.

So to answer your question:

So, since I am not familiar with AJAX, I just want to know if this is the usual way to operate, or if this is indeed a terrible idea as I think. What would be the proper way to do it?

Yes, if you use the default of 0, it probably is a terrible idea. But it doesn't have to be.

Other points from your question:

  1. Do you really need to go to the DB and get all the users each time. How about caching?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM