Setting a variable inside a function in JS - javascript

var last = 0;
function grabProducts(searchstring) {
var last = 0;
$.post('ajax/products', {
method: 'search',
string: searchstring,
category: $('#search_category').val(),
sort: $('.sort').val()
}, function (data) {
data = $.parseJSON(data);
$.each(data, function (index, b) {
last = "dada";
});
});
}
alert(last);
Gives me alert with "0". How can i make it set the variable to "dada"?

You can't make a setup like that work because $.post() is asynchronous. You'll have to put the "alert" in the callback function you pass to $.post().
var last=0;
function grabProducts(searchstring) {
var last=0;
$.post('ajax/products', { method: 'search', string: searchstring, category: $('#search_category').val(), sort: $('.sort').val() }, function(data) {
data = $.parseJSON(data);
$.each(data, function(index, b) {
last = "dada";
});
alert(last);
});
}
The whole point of the callback, in fact, is to provide you with a way to have code run when the HTTP request is complete.

When you POST something, It needs time for server to respond. Do this:
var last=0;
function grabProducts(searchstring) {
var last=0;
$.post('ajax/products', { method: 'search', string: searchstring, category: $('#search_category').val(), sort: $('.sort').val() }, function(data) {
data = $.parseJSON(data);
$.each(data, function(index, b) {
last = "dada";
});
alert(last);
});
}

Related

Change remote url based on search query

I have a select2 field which is retrieving data from a remote api. I can get that working. What I'm trying to do is change the remote url based on what the user has typed. If the first two letters typed are for example "AA" then search using a url and when the first two characters are "88" then search using another url.
This is my code so far:
this.selector.select2({
minimumInputLength: 2,
ajax: {
url: function(param){return 'http://localhost:3000/suggestions?&'},
dataType: 'json' ,
data: function (params) {
var query = {
search: params.term,
}
return query;
},
processResults: function(data) {
var results = [];
$.each(data, function (index, search) {
results.push({
id: search.id,
text: search.val
});
});
return {
"results":results
};
},
},
width: 'resolve',
});
I've looked but can't find an event which is fired when typing(searching).
According to docs the params argument passed to url callback is the same as in data callback. So you can rewrite your code as:
this.selector.select2({
minimumInputLength: 2,
ajax: {
url: function (params) {
var firstTwoLetters = params.term.slice(0, 2);
if (firstTwoLetters == '88') {
return 'some url';
} else if (firstTwoLetters == 'AA') {
return 'another url'
} else {
return 'http://localhost:3000/suggestions?&'
}
},
dataType: 'json',
data: function (params) {
var query = {
search: params.term,
}
return query;
},
processResults: function (data) {
var results = [];
$.each(data, function (index, search) {
results.push({
id: search.id,
text: search.val
});
});
return {
"results": results
};
},
},
width: 'resolve',
});
I hope I understood your last request correctly.
The oninput event occurs as you type.
note: I'd rather comment it and not use Answer, however, I have less than 50 rep.

jQuery wait for .each to finish and run ajax call

I have the following code:
var allChecks = [];
$('input[type=text]').each(function () {
var key = $(this).attr("id");
allChecks[key] = [];
}).promise()
.done(function () {
$('input[type=checkbox]').each(function () {
if (this.checked) {
var ref = $(this).attr('id');
$('.' + ref).each(function () {
allChecks[ref].push({
amount: $("#" + ref).text()
});
});
} else {
allChecks[ref].push({
amount: 0.00
});
}
}).promise()
.done(function () {
$.ajax({
cache: false,
type: 'POST',
data: {
allChecks: allChecks
},
url: '/process',
beforeSend: function () {
console.log("Processing your checks please wait...");
},
success: function (response) {
console.log(response);
},
error: function () {
console.log("Error");
}
});
});
});
My Ajax call runs but I see no data passed as parameters, like if the array allChecks is empty. As JavaScript runs synchronously, I'm expecting that whatever I place after each() will not run until each() is complete, so the Ajax call should run fine and nor give me no data passed as if the array allChecks is empty. Any help or solution on this would be appreciated. Thanks.

Dynamically send parameter in ajax-chosen

I am new to Jquery world.
I have these following codes:
$target.ajaxChosen({
type: 'GET',
url: '<s:url action="getFilterValueJSON" namespace="/cMIS/timetable"></s:url>?filterKey='+keyword,
dataType: 'json',
jsonTermKey: 'filterWord'
}, function (data) {
var terms = [];
mydata = data.valueMap;
$.each(mydata, function (i, val) {
terms.push({ value: i, text: val });
});
return terms;
});
It seems the variable 'keyword' does not dynamically changed its value. The value for 'keyword' comes from an element with on change event. Would someone enlighten me about this on how to solve this? Thanks in advance.
its better you compose your url object just before call
function onclick(keyword)
{
var url = '<s:url action="getFilterValueJSON" namespace="/cMIS/timetable"></s:url>?
filterKey='+keyword;
ajaxCall(url);
}
function ajaxCall(url)
{
$target.ajaxChosen({
type: 'GET',
url: url,
dataType: 'json',
jsonTermKey: 'filterWord'
}, function (data) {
var terms = [];
mydata = data.valueMap;
$.each(mydata, function (i, val) {
terms.push({ value: i, text: val });
});
return terms;
});
}

cannot call val() if initSelection() is not defined error in select2 plugin

I am using select2 plugin to load remote data. I am using an aspx page which returns JSON data and same is assigned to select2 plugin. After user selects some value from the select2 textbox, i am forcing page to postback. After the postback i am using following code to reload to set the text in the select2 textbox.
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
$('#e6').select2('val', '123');
But system is throwing following error: cannot call val() if initSelection() is not defined
Even if I define init, I am not able to set the value. I am using following code. Please help me set the value on the select2 textbox after the postback.
$(document).ready(function () {
$("#e6").select2({
placeholder: "Search for a movie",
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: "data.aspx",
dataType: 'json',
quietMillis: 1000,
data: function (term, page) {
return {
name: term
};
},
initSelection: function (element, callback) {
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
callback(data);
},
results: function (data) {
var results = [];
$.each(data, function (index, item) {
results.push({
id: item['Email'],
text: item['PatientID']
});
});
return {
results: results
};
},
},
});
});
window.onload = function () {
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
//When this is called system is throwing error
//This code is required to show the value in select2 textbox after the post back
$('#e6').select2('val', data);
}
$(document).ready(function () {
$("#e6").on("select2-selecting", function (e) {
//alert("selecting val=" + e.val + " choice=" + JSON.stringify(e.choice));
var id = document.getElementById('<%= savebtn.ClientID %>');
document.getElementById('<%= hdnFld.ClientID %>').value = e.val;
id.value = e.val;
//causes post back
id.click();
});
});
There is a mistake with your script. I had the same problem and I saw your question. After I read the API docs of Select2 I realised my error.
You should place the initSelection at the same level as ajax. e.g.
$("#e6").select2({
placeholder: "Search for a movie",
minimumInputLength: 1,
initSelection: function (element, callback) {
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
callback(data);
},
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: "data.aspx",
dataType: 'json',
quietMillis: 1000,
data: function (term, page) {
return {
name: term
};
},
results: function (data) {
var results = [];
$.each(data, function (index, item) {
results.push({
id: item['Email'],
text: item['PatientID']
});
});
return {
results: results
};
},
},
});

How to wait ajax callback result from another callback?

I have a method below:
self.getOrAddCache = function (key, objectFactory) {
var data = self.getFromCache(key);
if (!data) {
data = objectFactory();
if (data && data != null)
self.addToCache(key, data);
}
return data;
};
I use like this:
function getCities()
{
var cities = getOrAddCache(CacheKeys.Cities, function() {
var cityArray = new Array();
// get city informations from service
$.ajax({
type: "GET",
async: true,
url: "service/cities",
success: function (response) {
$.each(response, function(index, value) {
cityArray.push({
name: value.name,
id: value.id
});
});
}
});
if (cityArray.length > 0)
return cityArray;
else {
return null;
}
});
return cities;
}
getCities function always return null because getCities not waiting for completion async ajax request.
How can i resolve this problem? (Request must be async)
The best solution for this is to use Deferred objects. Since you require your AJAX call to be asynchronous, you should have your getCities function return a promise to return that data at some point in the future.
Instead of storing the raw data in the cache, you store those promises.
If you request a promise that has already been resolved, that will complete immediately. If there's already a pending request for the cached object, the async AJAX call will be started and all outstanding callbacks waiting for that promise will be started in sequence.
Something like this should work, although this is of course untested, E&OE, etc, etc.
self.getCached = function(key, objectFactory) {
var def = self.getCache(key);
if (!def) {
def = objectFactory.call(self);
self.addToCache(key, def);
}
return def;
}
function getCities() {
return getCached(CacheKeys.Cities, function() {
return $.ajax({
type: 'GET',
url: 'service/cities'
}).pipe(function(response) {
return $.map(response, function(value) {
return { name: value.name, id: value.id };
});
});
});
}
Note the usage of .pipe to post-process the AJAX response into the required format, with the result being another deferred object, where it's actually the latter one that gets stored in your cache.
The usage would now be:
getCities().done(function(cities) {
// use the cities array
});
With a callback:
function getCities(callbackFunction)
{
var cities = getOrAddCache(CacheKeys.Cities, function() {
var cityArray = new Array();
// get city informations from service
$.ajax({
type: "GET",
async: true,
url: "service/cities",
success: function (response) {
$.each(response, function(index, value) {
cityArray.push({
name: value.name,
id: value.id
});
});
callbackFunction(cityArray);
}
});
});
}
getCities(function(cityArray){
// do stuff
});
You can't return the result from a function fetching asynchronously the data.
Change your getCities function to one accepting a callback :
function fetchCities(callback) {
var cities = getOrAddCache(CacheKeys.Cities, function() {
var cityArray = new Array();
// get city informations from service
$.ajax({
type: "GET",
async: true,
url: "service/cities",
success: function (response) {
$.each(response, function(index, value) {
cityArray.push({
name: value.name,
id: value.id
});
});
if (callback) callback(cityArray);
}
});
});
}
And use it like this :
fetchCities(function(cities) {
// use the cities array
});
Note that it's technically possible, using async:true, to make the code wait for the response but don't use it : that's terrible practice and it locks the page until the server answers.
You seem to be contradicting yourself.
Something that is asynchronous, by definition, does not pause the script to wait for the end of it's execution. If it does wait, it cannot be asynchronous.
The best wayto fix this is by adding a callback function in your ajax success function that passes the end result to another function, which handles the rest of the execution.

Categories

Resources