How to avoid repeating the same $.ajax() call - javascript

I have two $.ajax() calls in my javascript code.
$.ajax({
url: 'http://localhost/webmap201/php/load_data.php',
data: {
tbl: 'district'
},
type: 'POST',
success: function(response) {
console.log(JSON.parse(response));
json_district = JSON.parse(response);
district = L.geoJSON(json_district, {
onEachFeature: return_district,
});
ctl_layers.addOverlay(district, "district", "Overlays");
ar_district_object_names.sort();
$("#text_district_find_project").autocomplete({
source: ar_district_object_names,
});
},
error: function(xhr, status, error) {
alert("Error: " + error);
}
}
);
$.ajax({
url: 'http://localhost/webmap201/php/load_data.php',
data: {
tbl: 'province'
},
type: 'POST',
success: function(response) {
console.log(JSON.parse(response));
json_province = JSON.parse(response);
province = L.geoJSON(json_province, {
onEachFeature: return_province,
});
ctl_layers.addOverlay(province, "province", "Overlays");
ar_province_object_names.sort();
$("#text_province_find_project").autocomplete({
source: ar_province_object_names,
});
},
error: function(xhr, status, error) {
alert("Error: " + error);
}
}
);
changes on both ajax are as below:
tbl: 'district' -> tbl: 'province'
json_district -> json_province
return_district -> return_province
(district, "district", "Overlays") -> (province, "province", "Overlays")
ar_district_object_names -> ar_province_object_names
$("#text_district_find_project") -> $("#text_province_find_project")
Is there a way I can call this $.ajax() inside a function with one parameter and call the function afterwards. As an example:
function lyr(shpName){
$.ajax({
url: 'http://localhost/webmap201/php/load_data.php',
data: {
tbl: `${shpName}`
},
type: 'POST',
success: function(response) {
console.log(JSON.parse(response));
json_shpName = JSON.parse(response);
shpName = L.geoJSON(json_shpName, {
onEachFeature: return_shpName,
});
ctl_layers.addOverlay(shpName, `${shpName}`, "Overlays");
ar_shpName_object_names.sort();
$("#text_shpName_find_project").autocomplete({
source: ar_shpName_object_names,
});
},
error: function(xhr, status, error) {
alert("Error: " + error);
}
}
);
}
lyr (district);
Can I use template strings? Can I use that a function inside a function. Any help would be highly appriceated.

Create a function for ajax call.
For eg.:-
function serviceajaxjson(_successfun, _failurefun, _url, _data, _async, _global) {
if (_successfun == null) _successfun = ajax_return_successfun;
if (_failurefun == null) _failurefun = ajax_return_failurefun;
if (_global != false) { _global = true; }
if (_async != false) { _async = true; }
$.ajax({
type: "POST",
url: _url,
data: _data,
global: _global,
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
async: _async,
success: _successfun,
error: ajax_return_error,
failure: _failurefun
});
}
function ajax_return_successfun(response) {
console.info("success for " + response.d);
}
function ajax_return_failurefun(response) {
console.error("failuer occoured for " + response);
}
function ajax_return_error(response) {
console.warn("error occoured for " + response);
}
// // // call the above function
function myResponseFn(response){
if(response.data){
// // your code...
}
}
var data = "{'tbl': 'district'}";
serviceajaxjson(myResponseFn,myResponseFn,"http://localhost/webmap201/php/load_data.php",data);

If you're using latest version of popular browser (IE's dead, use Edge instead), then the simplest answer is yes. You might need some tweaking on the parameters and its use, but it should work

Related

jQuery Ajax get value via function?

I have created a save(id) function that will submit ajax post request. When calling a save(id). How to get value/data from save(id) before going to next step. How to solve this?
For example:
function save(id) {
$.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success: function (data) {
return data;
},
error: function (error) {
return data;
}
});
}
Usage:
$('.btn-create').click(function () {
var id = 123;
data = saveArea(id); //get data from ajax request or error data?
if (data) {
window.location = "/post/" + data.something
}
}
You have two options, either run the AJAX call synchronously (not recommended). Or asynchronously using callbacks
Synchronous
As #Drew_Kennedy mentions, this will freeze the page until it's finished, degrading the user experience.
function save(id) {
return $.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
async: false,
data: JSON.stringify({
id: id,
})
}).responseText;
}
$('.btn-create').click(function () {
var id = 123;
// now this will work
data = save(id);
if (data) {
window.location = "/post/" + data.something
}
}
Asynchronous (recommended)
This will run in the background, and allow for normal user interaction on the page.
function save(id, cb, err) {
$.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success: function (data) {
cb(data);
},
error: err // you can do the same for success/cb: "success: cb"
});
}
$('.btn-create').click(function () {
var id = 123;
save(id,
// what to do on success
function(data) {
// data is available here in the callback
if (data) {
window.location = "/post/" + data.something
}
},
// what to do on failure
function(data) {
alert(data);
}
});
}
Just make things a bit simpler.
For starters just add window.location = "/post/" + data.something to the success callback.
Like this:
function save(id) {
return $.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success:function(data){
window.location = "/post/" + data.something
}
}).responseText;
}
Or by adding all your Ajax code within the click event.
$('.btn-create').click(function () {
var id = "123";
$.ajax({
type: "POST",
url: "/post/",
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({
id: id,
}),
success: function (data) {
window.location = "/post/" + data.something
},
error: function (error) {
console.log(error)
}
});
}

Dropbox API: Sending Data Via Ajax to Controller

I am using the Dropbox API JavaScript Chooser and want to return the data from the response into my Controller
The Javascript Options for the Dropbox API
options = {
success: function (files) {
$.ajax({
url: '/FileTransfer/FileData',
type: "POST",
dataType: "json",
//data: JSON.stringify(files[0]),
data: files,
success: function (result) {}
});
},
cancel: function () {},
linkType: "preview",
multiselect: true
};
Controller Action
My controller action currently doesn't do anything at the moment but will eventually cache the output data into a model once i can get data to be passed into it, which is hence my problem.
public JsonResult FileData(string model)
{
return Json(new { success = true });
}
ADyson`s hints have helped me solve my problem, thank you
Altered code below, note the change to data: and then deserialised in the Controller
Javascript
options = {
success: function (files) {
$.ajax({
url: '/FileTransfer/FileData',
type: "POST",
dataType: "json",
data: { result : JSON.stringify(files) },
//data: files,
success: function (result) {
$("#FileList").load('/FileTransfer/Cloud');
console.log(result);
},
error : function (jQXHR, textStatus, errorThrown) {
//alert("An error occurred: " + jQXHR.status + " " + textStatus + " " + errorThrown);
}
});
},
cancel: function () {},
linkType: "preview",
multiselect: true
};
Controller
public JsonResult FileData(string result)
{
var convertedResult = JsonConvert.DeserializeObject<List<DropboxFile>>(result);
CacheEntity(convertedResult);
return Json(new { success = true });
}
Refactored code following suggestion
Javascript
options = {
success: function (files) {
$.ajax({
url: '/FileTransfer/FileData',
type: "POST",
dataType: "json",
data: { result : files},
success: function (result) {
$("#FileList").load('/FileTransfer/Cloud');
},
error : function (jQXHR, textStatus, errorThrown) { }
});
},
cancel: function () {
},
linkType: "preview",
multiselect: true
};
Controller
public JsonResult FileData(List<DropboxFile> result)
{
CacheEntity(result);
return Json(new { success = true });
}

Loading AJAX calls one after the other

I have the following 3 AJAX function, and the problem is that it loads sessionAllCoursePage3 first then sessionAllCoursePage2 then sessionAllCoursePage1, I wanted to be inverse. I want to ensure that page1 is loaded first, then page 2, page 3, etc.
// Retrieve last 9 session
$.ajax({
type: "POST",
data: { run: true, providerName: $('#providerName').val() },
url: '/app/functions/sessionAllCoursePage1.php',
cache: false,
success: function(response) {
// Response is value returned from php
$('#contentPage1').html(response);
return false;
}
});
// Retrieve the next 9 session
$.ajax({
type: "POST",
data: { run: true, providerName: $('#providerName').val() },
url: '/app/functions/sessionAllCoursePage2.php',
cache: false,
success: function(response) {
// Response is value returned from php
$('#contentPage2').html(response);
return false;
}
});
// Retrieve the next 9 session
$.ajax({
type: "POST",
data: { run: true, providerName: $('#providerName').val() },
url: '/app/functions/sessionAllCoursePage3.php',
cache: false,
success: function(response) {
// Response is value returned from php
$('#contentPage3').html(response);
return false;
}
});
I'd suggest you chain them with promises:
// Retrieve last 9 session
$.ajax({
type: "POST",
data: {
run: true,
providerName: $('#providerName').val()
},
url: '/app/functions/sessionAllCoursePage1.php',
cache: false
}).then(function(response) {
$('#contentPage1').html(response);
return $.ajax({
type: "POST",
data: {
run: true,
providerName: $('#providerName').val()
},
url: '/app/functions/sessionAllCoursePage2.php',
cache: false
}).then(function(response) {
$('#contentPage2').html(response);
return $.ajax({
type: "POST",
data: {
run: true,
providerName: $('#providerName').val()
},
url: '/app/functions/sessionAllCoursePage3.php',
cache: false
});
}).then(function(response) {
$('#contentPage3').html(response);
});
Or, using a little more shared code:
function ajaxCommon(url, resultId) {
return $.ajax({
type: "POST",
url: url,
data: {
run: true,
providerName: $('#providerName').val()
},
cache: false
}).then(function(result) {
$("#" + resultId).html(result);
});
}
ajaxCommon('/app/functions/sessionAllCoursePage1.php', 'contentPage1').then(function() {
return ajaxCommon('/app/functions/sessionAllCoursePage2.php', 'contentPage2');
}).then(function() {
return ajaxCommon('/app/functions/sessionAllCoursePage3.php', 'contentPage3');
});
Or, a little more table/loop driven:
function ajaxCommon(url, resultId) {
return $.ajax({
type: "POST",
url: url,
data: {run: true, providerName: $('#providerName').val()},
cache: false
}).then(function(result) {
$("#" + resultId).html(result);
});
}
[1,2,3].reduce(function(p, item) {
return p.then(function() {
return ajaxCommon('/app/functions/sessionAllCoursePage' + item + '.php', 'contentPage' + item);
});
}, Promise.resolve());
Just place your asynchronous code inside some request callback (e.g. success). Didactically:
var firstRequestOptions = {
success: function () {
secondRequest();
}
};
var secondRequestOptions = {
success: function () {
thirdRequest();
}
};
var thirdRequestOptions = {
success: function () {
firstRequest();
}
};
var firstRequest = function () {
console.log('request 1');
$.ajax(firstRequestOptions);
};
var secondRequest = function () {
console.log('request 2');
$.ajax(secondRequestOptions);
};
var thirdRequest = function () {
console.log('request 3');
$.ajax(thirdRequestOptions);
};
Then:
firstRequest();
The log should be:
> request 1
> request 2
> request 3
> request 1
> request 2
...
You can use Array.prototype.shift(), String.prototype.match() with Regexp /\d/ to match digit character in url, .then()
function request(url) {
return $.ajax({
type: "POST",
data: {run: true, providerName: $('#providerName').val()},
url: url,
cache:false,
success: function (response) {
$('#contentPage' + url.match(/\d/)[0]).html(response);
}
});
}
var urls = ['/app/functions/sessionAllCoursePage1.php'
, '/app/functions/sessionAllCoursePage2.php'
, '/app/functions/sessionAllCoursePage3.php'];
request(urls.shift())
.then(function re() {
if (urls.length) {
request(urls.shift()).then(re)
}
})
// can use `.catch()` here at jQuery 3.0+
.fail(function(jqxhr, textStatus, errorThrown) {
// handle error
console.log(errorThrown);
});
plnkr http://plnkr.co/edit/fREO6Jzw65gq2s3jrwjp?p=preview

jquery autocomplete - save data to DB when list item is clicked (select event)

i've read a lot about jq autocomplete, but it seems, there is no way to make an ajax request while the select event is fired.
I will write the search query into an DB-Table only when the element is clicked.
Firebug shows the url in redGET http://server.ccc/api/my/logSearchQuery?a=searchquery&b=11&v=0
$(document).ready(function(e){
var results = [];
var _request = null;
$("#input").autocomplete({
source: function( request, response ) {
_request = request;
$.ajax({
url: "http://dataserver",
dataType: "jsonp",
jsonp: 'json.wrf',
data: {
q: GenerateSearchQuery(request.term)
},
success: function( data ) {
results = $.map(data.response.docs, function(item) {
return {
label: item.Name,
value: {
id:cid
}
};
});
response(results);
}
});
},
minLength: 3,
select: function( event, ui ) {
event.preventDefault();
// ---------------- here is what i've tried, but it fails----------------------
$.ajax({
url: "api/my/logSearchQuery",
type: "get",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: {"a": encodeURIComponent(_request.term), "b": results.length, "v": 0},
success: function(data){
console.log(data);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest+ " : "+ errorThrown + " : " + textStatus);
}
});
if (ui.item.value != "searchAll") {
self.location = "/list/"+ui.item.value.id;
} else {
$('#searchForm').submit();
}
}
});});
The Ajax call works into the source event, but thats not the right place i think.
The ajax errors are empty.
Please help.
Yes, i am a beginner;-)
The problem was, that the code under the ajax call...
select: function( event, ui ) {
event.preventDefault();
// ---------------- here is what i've tried, but it fails----------------------
$.ajax({
url: "api/my/logSearchQuery",
type: "get",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: {"a": encodeURIComponent(_request.term), "b": results.length, "v": 0},
success: function(data){
console.log(data);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(XMLHttpRequest+ " : "+ errorThrown + " : " + textStatus);
}
});
//----------this part---------------
if (ui.item.value != "searchAll") {
self.location = "/list/"+ui.item.value.id;
} else {
$('#searchForm').submit();
}
}
gets fired during the ajax call is working (asynchronous).
So i've putted the this part into the complete: event of $.ajax
complete: function(xhr, status){
if (ui.item.value != "searchAll") {
self.location = "/some /"+ui.item.value.pflnr;
} else {
$('#seachBar_searchForm').submit();
}
}
now it works fine.

Jquery Autocomplete ajax request only if item from previous ajax request data is not matching

I am using jQuery Autocomplete.
It's making an AJAX request on every keypress which I don't want. If data from a previous AJAX request matches a search it should not make any more AJAX requests.
<script>
$('#tags').autocomplete({
source: function (request, response) {
$.ajax({
url: '/TestDDl/Index',
// data: "{ 'prefix': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.user, function (item) {
return {
label: data.name,
val: data.val
}
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
autoFocus: true,
keypress: function (event, ui) {
alert('Not Selected');
if (!ui.item) {
alert('Not Selected');
}
}
});
});
Here if I am typing the name of a user which is already in previous AJAX request data, it should not make an AJAX request on next the keypress.
You can declare a variable, assing user input to it, then update it in your success function. And just before making next call, check if your variable matches the next data.
Something like this:
<script>
var recent = '';
$('#tags').autocomplete({
source: function (request, response) {
if (recent == request.term) {
return;
}
recent = request.term;
$.ajax({
url: '/TestDDl/Index',
data: "{ 'prefix': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.user, function (item) {
return {
label: data.name,
val: data.val
}
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
autoFocus: true,
keypress: function (event, ui) {
alert('Not Selected');
if (!ui.item) {
alert('Not Selected');
}
}
});
</script>
<script>
window.xyz = []; //For saving history
$('#tags').autocomplete({
source: function (request, response) {
if(xyz[request]){
response(xyz[request]); // Return previously saved data
}else(
$.ajax({
url: '/TestDDl/Index',
// data: "{ 'prefix': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
var res = $.map(data.user, function (item) {
return {
label: data.name,
val: data.val
}
});
xyz[request]=res; //set data to reuse later
response(res)
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
}
},
autoFocus: true,
keypress: function (event, ui) {
alert('Not Selected');
if (!ui.item) {
alert('Not Selected');
}
}
});
</script>
Your next ajax reques should be in the Success function of the first ajax request.Buid the logic there.If you find the match don't call the second ajax request else call the second ajax request and all should be in the success function of the first ajax request.

Categories