Ajax Making Mutiple Requests to the API - javascript

I have just started learning javascript and what I am doing is making request to my Django API. So I found I can use Ajax requests to do so.
SO I made a search bar that would call the API after waiting 1 sec on the keyup action.
input.addEventListener('keyup', function (e) {
clearTimeout(timeout);
timout = setTimeout(function () {
runScript(input.value);
}, 1000);
});
The runscript function is the one making Ajax requests
function runScript(input) {
var jqXHR = $.ajax({
url: "http://localhost:8090/api/movie/?name=" + input,
datatype: 'json',
success: callbackFunc
});
return jqXHR.responseText;
}
and the callbackFunc is what I would like to do with the response
function callbackFunc(response) {
// do something
}
The problem is that ajax is making multiple requests to the API. How do I stop Ajax from making multiple requests ?
Related: Prevent ajax call from firing twice, Ajax, prevent multiple request on click

You can use the stopImmediatePropagation method which is meant for cases like this. https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation.
If several listeners are attached to the same element for the same event type, they are called in the order in which they were added. If stopImmediatePropagation() is invoked during one such call, no remaining listeners will be called.
You only need to add the method call on you timeout function like this
timeout = setTimeout(function () {
e.stopImmediatePropagation()
runScript(input.value);
}, 1000);
Full fiddle here https://jsfiddle.net/zgranda/fujw6tvp/9/

Related

Sending an AJAX call before all other AJAX calls

I need to check for a condition and run an AJAX call before sending other AJAX calls on my web app.
I was thinking about putting this AJAX call in a beforeSend on ajaxSetup with async: false (to prevent my initial call from running before this one has completed).
Something like this:
//I set an event that fires:
$.ajax({
type: "GET",
url: my_url,
beforeSend: function() {
//do something, like show a spinner loader gif
}
});
//Somehwere in my app I also have:
$.ajaxSetup({
beforeSend: function() {
if(x===1){
$.ajax({
type: "GET",
url: my_url/fetch_something,
async:false
});
}
}
});
Will my beforeSend on the first AJAX call overrun the one in the ajaxSetup? Is there a way to approach this better?
Better idea of my app:
I have a lot of Ajax calls through the app, each call sends a security hash on the headers to validate the user, these hashes have a time limit as well (both hash and time limit are saved in localStorage)
What I want from ajax setup (and the condition in it) is to check for the time limit - if time_limit < current_time than run an ajax call to refresh the users hash.
This isn't an exercise for 1 or 2 calls, I literally have 20+ growing Ajax calls on my app that make use of the users hash and it's very impractical to make this check in every single one of them.
UPDATED:
Have one method on an interval that sets up the 'session'/local-storage
var refreshing = false;
var intervalID;
$(document).ready(function(e){
var delay = 1234;
intervalID = window.setInterval(setupInterval, delay);
});
function setupInterval(){
refreshing = true;
$.ajax(URL).done(function(r) { //do stuff
setupStorage(r);
refreshing = false;
});
}
function setupStorage(info){
//setup whatever here
}
OLD:
Could you use some logic in your ready function to gate what you need to do?
So basically call one ajax call -> if false, just schedule your latter methods, otherwise run the setup one and on completion schedule the latter method.
Some pseudo-code:
var refresh = false;
$(document).ready(function(e){
$.ajax(URL).done( function(r) {
if(r) {
routeOne();
} else {
latter();
}
});
});
function routeOne(){
$.ajax(URL).done(function(r) { //do stuff
latter();
});
}
function latter(){
//All other ajax calls
}
I'll put some more thought into this let me finish my coffee first...
EDIT:
Based on your updated description could it be possible for you to schedule a setInterval to run the checking method/hash update on the time interval that you need, and is the time interval on your server static or variable? Facebook does this with a heartbeat, I've used this type of logic with some 'locking' functionality in a web-app. If you schedule the interval properly it should not interrupt any other ajax calls.
Try overriding $.ajax to make a "pre-call" before passing in your given query options:
var oldAjax = $.ajax;
$.ajax = function() {
var args = arguments;
oldAjax({
type: "GET",
url: "/echo/html/",
success: function(result){
// do something here to check result
// if result is good, do the request:
return oldAjax.apply($, args);
// if its bad, handle the error
}
});
}
Here's a fiddle to demonstrate: http://jsfiddle.net/NF76U/
I suggest the use of .done() ( $.Deferred object)
function AjaxCall() {
return //code of your ajax without async:false
}
function anotherAjaxCall{
return //code of you ajax call
}
AjaxCall.done(anotherAjaxCall);
Avoid using async:false it's a deprecated practice and it stucks browsers

Periodically send ajax requests

There is a page and I want periodically to make "background" ajax requests. So the page is loaded then it should send ajax requests in a certain amount of time.
I might use cron for that. I have never use previously so I'm wondering if it would fit for that task. Is there any other more simple way?
P.S. The time delay will be about 5 minutes.
Since there is essentially an unknown delay between the time you send out an AJAX request and the time you receive a complete response for it, an oftentimes more elegant approach is to start the next AJAX call a fixed amount of time after the prior one finishes. This way, you can also ensure that your calls don't overlap.
var set_delay = 5000,
callout = function () {
$.ajax({
/* blah */
})
.done(function (response) {
// update the page
})
.always(function () {
setTimeout(callout, set_delay);
});
};
// initial call
callout();
Cron is run on the serverside and you are using HTML and AJAX, so you should solve this issue in Javascript :-)
By using something like setInterval you can keep executing a function, your case might be something like polling a url via AJAX:
function updatePage(){
// perform AJAX request
}
setInterval(updatePage, 5000);
Depending on your rails version you may be able to use periodically_call_remote, otherwise you'll need the jquery alternative that #Bitterzoet described.
More info in this question.
You can send ajax request in four second like this:
setInterval(get_news, 4000);
function get_news(){
$.ajax('/dashboards/get_news', {
type: 'POST',
success: function(result) {
if(result > 0){
$('#div_1').text("See "+result+" new messages");
$('#div_1').show();
}
else{
$('#div_1').css('display', 'none');
}
},
error: function() {
// alert("Error")
}
});
}
Are you using jquery? If so, you can implement this method:
// first, you need asing a callback timer
var timeout = 300; //milliseconds
// this method contain your ajax request
function ajaxRequest() { //function to ajax request
$.ajax({
url: "/url/to/request/"
}).done(function(data) {
alert("response is: " + data);
});
}
$(document).on("ready", function(){
//this method will be called every 300 milliseconds
setInterval(ajaxRequest, timeout);
});

ajaxStop() doesn't fire

This is the code that wasn't working:
$(document).ajaxStop(function() {
$(this).unbind("ajaxStop"); //prevent running again when other calls finish
// Display everything
display();
});
And here's my Ajax function:
function getAjax(url, callback) {
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
$.ajax({
url: url,
type: "GET",
dataType: "jsonp",
success: callback
});
}
Why does ajaxStop() never fire?
You'll notice I was making JSONP requests. It took me forever to find this, but the answer to this issue can be found here.
From the ticket:
JSONP requests are not guaranteed to complete (because errors are not
caught). jQuery 1.5 forces the global option to false in that case so
that the internal ajax request counter is guaranteed to get back to
zero at one point or another.
If you want all requests to fire the events, no matter what (and at the risk of the same inconsistencies 1.4.4 exhibited), you can use the following prefilter:
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
Case in point: http://jsfiddle.net/X4JTx/

keyup(function()) ajax request delay - jQuery

I have a jQuery Ajax request, that I want to call with text input, and so I nested it inside keyup(function(). This works fine.
$("#text_box").keyup(function() {
//AJAX REQUEST
});
But this behaves buggy sometimes. When I input some text very fast, I am getting results for input word with some last letters of the original input word omitted (may be some fault with browser). I want the ajax request to be sent when there is no input activity for a second, I mean, if I input text very fast and rest for a second (means I made the input). How can I do this?
It sounds as if you get results from a previous ajax call. Use a timer with setTimeout and clearTimeout.
var timer = null;
$("#text_box").keyup(function() {
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(someFunction, someDelay);
});
Where someFunction is a function which does your ajax call and someDelay is the delay you want to wait before doing the call, after the user has typed, in ms.
As you are already using jQuery you could use the debounce plugin from Ben Aleman.
Example from the page
// Bind the not-at-all debounced handler to the keyup event.
$('input.text').keyup( text_1 );
// Bind the debounced handler to the keyup event.
$('input.text').keyup( $.debounce( 250, text_2 ) ); // This is the line you want!
omg. for somebody who will search in 2014...
function sendAjax() {
setTimeout(
function() {
$.ajax({
url: "url.php",
type: "POST",
data: data,
success: function(data) {
$("#result").html(data);
}
});
}, 2000);
}
<input onkeyup="function()">

how to call a specific function on every ajax request

I have a problem, that I have several pages in my project and I used a lot of ajax requests in my project, but now I think that whenever an ajax request is called a function will called and whenever that request ends another function will call. How can I do this globally I know I can put this in every ajax request but I need a solution which I do in one place and it works all over the project.
$(document).read(function(){
// Suppose this document load function is written on layout page and every page is inherited from this page
});
Use ajaxSetup, for example
$.ajaxSetup({
beforeSend: function() {
console.log('test');
},
complete: function() {
console.log('completed');
}
});
will setup beforeSend handler for every ajax request. Note that ajaxSetup can take any option that $.ajax can.
You should create a wrapper function for your ajax, then use that function. that way, you have "central" control over the ajax call. something like:
//fast and crude way to extend jQuery
$.fn.customAjax = function(params){
//contains defaults and predefined functions
var defaults = {
complete : function(){...default complete hander...},
beforeSend : function (){...default beforeSend handler}
...
}
//merge settings
var finalParams = $.extend({},defaults,params);
//call ajax and return the deferred
return $.ajax(finalParams);
}
//use it like
$.customAjax({
url : ...,
method : ...,
data: ...,
complete : function(){...} //redefining in the call will override the defaults
});
.ajaxStart
Register a handler to be called when the first Ajax request begins.
.ajaxSucess
Attach a function to be executed whenever an Ajax request completes successfully.
for Detail doc:
http://api.jquery.com/category/ajax/
Try something like this:
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$.ajax({
url: "anotherMethod.html",
context: document.body
});
});
});
That means whenever ajax call completed successfully call your desire call.
It doesn't have a bug when complete. Click on Like, if work for you
$(document).ajaxSend(function(event, jqXHR, settings) {
$('#general-ajax-load ').fadeIn();
});
$(document).ajaxComplete(function(event, jqXHR, settings) {
$('#general-ajax-load ').fadeOut();
});

Categories

Resources