I have this code fragment:
if(!encryption_state){
if(cKey=="" || cKey==null){
cKey=getKey(aid); //here we trying to obtain key
if(cKey!="" && cKey!=null && cKey!=undefined){
if(isJSON(jKey) && encryption_state){
var tjKey = JSON.parse(jKey);
tjKey[aid] = cKey;
jKey = JSON.stringify(tjKey);
}else{
jKey = json.stringify({aid: cKey});
}
encryption_state=true;
}
}
if(!encryption_state){
if(cKey=="" || cKey==null){
cKey=rndstr(32); //generate string
}
var arr = {};
if(isJSON(jKey)) arr = JSON.parse(jKey);
arr[aid] = cKey;
jKey = JSON.stringify(arr);
encryption_state = true;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
But when i call getKey(kaid) function:
function getKey(kaid){
$.ajax({
method: "POST",
url: "/?mod=key&fnc=syncKey",
data: {
aid: kaid
},
done: function(data) {
var tret = (JSON.parse(data)['msg']);
return tret;
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Browsers don't continue do function getKey(), they do next commands in parent function, i don't know why they ignore web server answer and don't let function return server response :(
in general, an ajax call is asynchronous. That means, a sequence like
var a = 0;
a = getAwithAjaxFromServer(...);
console.log(a);
will immediately print "0" while the ajax is still runnng.
Your entire logic with cleyand encryption_state has to be put into the done function:
if(!encryption_state){
if(cKey=="" || cKey==null){
cKey=getKey(aid);
}
}
and in your ajax:
function getKey(kaid){
$.ajax({
method: "POST",
url: "/?mod=key&fnc=syncKey",
data: {
aid: kaid
},
done: function(data) {
var tret = (JSON.parse(data)['msg']);
.... PUT ALL THE LOGIC HERE .....
}
});
}
You must understand asynchronous mechanism in javascript to continue calling ajax. There are a lot of resources and stackoverflow questions. For example: https://www.pluralsight.com/guides/front-end-javascript/introduction-to-asynchronous-javascript
So, you can convert the code so:
if(!encryption_state){
var serverKeyCallback = function(cKey) {
if(cKey!="" && cKey!=null && cKey!=undefined){
if(isJSON(jKey) && encryption_state){
var tjKey = JSON.parse(jKey);
tjKey[aid] = cKey;
jKey = JSON.stringify(tjKey);
}else{
jKey = json.stringify({aid: cKey});
}
encryption_state=true;
}
};
var localKeyCallback = function(cKey) {
if(!encryption_state){
if(cKey=="" || cKey==null){
cKey=rndstr(32); //generate string
}
var arr = {};
if(isJSON(jKey)) arr = JSON.parse(jKey);
arr[aid] = cKey;
jKey = JSON.stringify(arr);
encryption_state = true;
}
}
manageKey(cKey, aid, serverKeyCallback, localKeyCallback);
}
function manageKey(cKey, kaid, serverKeyCallback, localKeyCallback) {
if(cKey=="" || cKey==null) {
$.ajax({
method: "POST",
url: "/?mod=key&fnc=syncKey",
data: {
aid: kaid
},
done: function(data) {
var tret = (JSON.parse(data)['msg']);
serverKeyCallback(tret);
localKeyCallback(tret);
}
});
}
else {
localKeyCallback(cKey);
}
}
Defining two encapsulated pieces of code, one to execute after serverResponse, and the other to execute after the serverResponse or when you have the cKey locally stored. I haven't tested the code, but it must work as you expect.
Related
I am making a ajax calls that returns me some data from the server. I work on string function on the data that come from ajax call. From my knowledge i can see the string operation begins before the ajax call gets over. Often giving me undefined error. Here is my ajax call
$.ajax({
type: "POST",
url: "/add_director",
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(data) {
$('#addDirModal').modal('hide');
insertDirector(data);
},
error : function(xhr ,status ,error)
{
console.log(xhr);
alert(xhr);
}
});
Here is my insertDirector function
function insertDirector(data){
console.log(data);
if (data.msg == "1") {
$.each(data,function(key,value){
var dir_name = value.dir_name;
var dir_pan = value.dir_pan;
var dir_din = value.dir_din;
var dir_addr = value.dir_addr;
var dir_id = value.id;
var dir_img = value.dir_img;
if (dir_name.val().length > 15) {
var dir_r_name = dir_name.substr(0,15);
}
else{
var dir_r_name = dir_name;
}
});
}
}
Here when i work on substr() it throws the error Cannot read property 'val' of undefined. I can see this is because the substr() is executed before the ajax request is completed. how do i fix this ?
EDITED
Here is the response
{"msg":"1","director":{"dir_name":"Naveen","dir_pan":"AAAAA1111B","dir_din":"123456","dir_addr":"dsadasdasdasdsadasdas","dir_img":"1490852438.jpg","user_id":3,"updated_at":"2017-03-30 05:40:38","created_at":"2017-03-30 05:40:38","id":15}}
Its not clear why you use the $.each here (you can omit it and use data.director instead of value), but if it is possible that your data contain several 'director' objects and you want to iterate through all of them, then you should change the insertDirector code to skip the 'msg' key as it doesn't have dir_name, dir_plan, ... properties:
function insertDirector(data) {
console.log(data);
if (data.msg == "1") {
$.each(data, function (key, value) {
if (key == "director") { //or if (key != "msg")
var dir_name = value.dir_name;
var dir_pan = value.dir_pan;
var dir_din = value.dir_din;
var dir_addr = value.dir_addr;
var dir_id = value.id;
var dir_img = value.dir_img;
var dir_r_name = (dir_name.length > 15 ? dir_name.substr(0, 15) : dir_name);
//if (dir_name.length > 15) {
// var dir_r_name = dir_name.substr(0, 15);
//}
//else {
// var dir_r_name = dir_name;
//}
}
});
}
}
also, note that dir_name.val().length is wrong as dir_name is a string (.val() is not required)
change
if (dir_name.val().length > 15) {
var dir_r_name = dir_name.substr(0,15);
}
to
if (dir_name.length > 15) {
var dir_r_name = dir_name.substr(0,15);
}
try this way :
function insertDirector(data) {
console.log(data);
if (data.msg == "1") {
var dir_name = data.director.dir_name;
var dir_pan = data.director.dir_pan;
var dir_din = data.director.dir_din;
var dir_addr = data.director.dir_addr;
var dir_id = data.director.id;
var dir_img = data.director.dir_img;
if (dir_name.length > 15) {
var dir_r_name = dir_name.substr(0, 15);
}
else {
var dir_r_name = dir_name;
}
}
}
After seeing the data you posted, it is easy to find issue.
Here, the issue is:
Your function:
function insertDirector(data){
console.log(data);
if (data.msg == "1") {
$.each(data,function(key,value){
var dir_name = value.dir_name;
var dir_pan = value.dir_pan;
var dir_din = value.dir_din;
var dir_addr = value.dir_addr;
var dir_id = value.id;
var dir_img = value.dir_img;
if (dir_name.val().length > 15) {
var dir_r_name = dir_name.substr(0,15);
}
else{
var dir_r_name = dir_name;
}
});
}
}
Here, when you do $.each, every object inside data will be traversed. Now, your first value inside data is msg:1. This is not a object. As a result, on first iteration, key is 'msg' but value is '1'. Now this value can't have dir_name so undefined is returned. As a result dir_name.val() generates error.
Try it like this:
function insertDirector(data){
console.log(data);
if (data.msg == "1") {
$.each(data,function(key,value){
if(key==="director"){
var dir_name = value.dir_name;
var dir_pan = value.dir_pan;
var dir_din = value.dir_din;
var dir_addr = value.dir_addr;
var dir_id = value.id;
var dir_img = value.dir_img;
if (dir_name.val().length > 15) {
var dir_r_name = dir_name.substr(0,15);
}
else{
var dir_r_name = dir_name;
}
}
});
}
}
What I like is the best way to handle my .fail() & .done() when my ajax request returns with a assoc array that I parse.
This is my current code and my current problem is .fail(). always firing.
Note: I tested my something.php and its giving me the right response when it fail or when it succeeded this is the actual response to my something.php
Fail :
{
"ac":"failed"
}
Success :
{
"alias": "cd9d0e2e",
"sso": "http://somethin.com/home/site/cd9d0e2e?dm_sso=2!dsa654654sa56d FGfre4f645465fTIxYWE3NGZkMzk0NGM3NzIyMWFhNWQyMTgifQ",
"ru": "http://somethin.com/login/resetpwd?uuid=asd1as3d1as321d-4370-be5d-123a3s2d1a3sd13a2s",
"ac": "something#sample.com",
"fn": "Fish",
"ln": "Fillet"
}
$(document).ready(function(){
$('#btn-create').click(function(e){
e.preventDefault();
var cSite = createSite();
cSite.done(sendMail).fail(failOption).always(alwaysOption);
}
});
function createSite() {
var promise = $.Deferred();
$.ajax({
url: 'something.php',
method: 'POST',
data:"template_id="+template_id+"&original_url="+original_url+"&email="+email+"&first_name="+first_name+"&last_name="+last_name
}).then(function(data) {
var dataa = JSON.parse(data);
//debugger;
if(dataa.ac === 'failed') {
promise.reject(dataa);
} else {
promise.resolve(dataa);
}
});
return promise;
}
function sendMail(dataa) {
console.log(dataa);
}
You can return the promise form your createSite function.
var cSite = createSite(); and then use with .then, .done, .always or .fail etc.
$(document).ready(function() {
$('#btn-create').click(function(e) {
e.preventDefault();
var cSite = createSite();
cSite.done(function(resp) {
var dataa = JSON.parse(resp);
sendMail(dataa);
}).fail(failOption).always(alwaysOption);
});
});
function createSite() {
var promise = $.ajax({
url: 'something.php',
method: 'POST',
data: "template_id=" + template_id + "&original_url=" + original_url + "&email=" + email + "&first_name=" + first_name + "&last_name=" + last_name
})
return promise;
}
function sendMail(dataa) {
console.log(dataa);
}
Okay I figure it out now .. this is the code that works now.
$(document).ready(function(){
$('#btn-create').click(function(e){
//debugger;
e.preventDefault();
$(this).html('Creating Site');
var template_id = $("#template_id").val();
var original_url = $("#original_url").val();
var email = $("#email").val();
var first_name = $("#first_name").val();
var last_name = $("#last_name").val();
$.ajax({
url: 'create-site-con.2.php',
method: 'POST',
data:"template_id="+template_id+"&original_url="+original_url+"&email="+email+"&first_name="+first_name+"&last_name="+last_name
}).done(function(resp) {
var dataa = JSON.parse(resp);
if (dataa.ac === "failed"){
failOption(dataa);
}
else{
sendMail(dataa);
}
});
});//click
});//doc ready
This is what the code below does:
Goes to a table in a database and retrieves some search criteria I will send to Google API (the PHP file is getSearchSon.php)
After having the results, I want to loop around it, call the Google API (searchCriteriasFuc) and store the results in an array
The last part of the code is doing an update to two different tables with the results returned from Google API (updateSearchDb.php)
In my code, I am using setTimeout in a few occasions which I don't like. Instead of using setTimeout, I would like to properly use callback functions in a more efficient way (This might be the cause of my problem) What is the best way of me doing that?
$(document).ready(function() {
$.ajax({
url: 'getSearchSon.php',
type: 'POST',
async: true,
dataType: 'Text',
/*data: { }, */
error: function(a, b, c) { alert(a+b+c); }
}).done(function(data) {
if(data != "connection")
{
var dataSent = data.split("|");
var search_criterias = JSON.parse(dataSent[0]);
var date_length = dataSent[1];
var divison_factor = dataSent[2];
var length = search_criterias.length;
var arrXhr = [];
var totalResultsArr = [];
var helperFunc = function(arrayIndex)
{
return function()
{
var totalResults = 0;
if (arrXhr[arrayIndex].readyState === 4 && arrXhr[arrayIndex].status == 200)
{
totalResults = JSON.parse(arrXhr[arrayIndex].responseText).queries.nextPage[0].totalResults;
totalResultsArr.push(totalResults);
}
}
}
var searchCriteriasFuc = function getTotalResults(searchParam, callback)
{
var searchParamLength = searchParam.length;
var url = "";
for(var i=0;i<searchParamLength;i++)
{
url = "https://www.googleapis.com/customsearch/v1?q=" + searchParam[i] + "&cx=005894674626506192190:j1zrf-as6vg&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM&dateRestrict=" + date_length;
arrXhr[i] = new XMLHttpRequest();
arrXhr[i].open("GET", url, true);
arrXhr[i].send();
arrXhr[i].onreadystatechange = helperFunc(i);
}
setTimeout(function()
{
if (typeof callback == "function") callback.apply(totalResultsArr);
}, 4000);
return searchParam;
}
function callbackFunction()
{
var results_arr = this.sort();
var countResultsArr = JSON.stringify(results_arr);
$.ajax({
url: 'updateSearchDb.php',
type: 'POST',
async: true,
dataType: 'Text',
data: { 'countResultsArr': countResultsArr },
error: function(a, b, c) { alert(a+b+c); }
}).done(function(data) {
var resultsDiv = document.getElementById("search");
if(data == "NORECORD") resultsDiv.innerHTML = 'Updated failed. There was a problem with the database';
else resultsDiv.innerHTML = 'Update was successful';
}); //end second ajax call
}
//llamando funcion principal
var arrSearchCriterias = searchCriteriasFuc(search_criterias, callbackFunction);
}
else
{
alert("Problem with MySQL connection.");
}
}); // end ajax
});
How you did it in 2015
Callbacks are things of the past. Nowadays you represent result values of asynchronous tasks with Promises. Here is some untested code:
$(document).ready(function() {
$.ajax({
url: 'getSearchSon.php',
type: 'POST',
async: true,
dataType: 'text'
/*data: { }, */
}).then(function(data) {
if (data == 'connection') {
alert("Problem with MySQL connection.");
} else {
var dataSent = data.split("|");
var search_criterias = JSON.parse(dataSent[0]);
var date_length = dataSent[1];
var divison_factor = dataSent[2];
return Promise.all(search_criterias.map(function(criteria) {
return $.ajax({
url: "https://www.googleapis.com/customsearch/v1"
+ "?q=" + criteria
+ "&cx=005894674626506192190:j1zrf-as6vg"
+ "&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM"
+ "&dateRestrict=" + date_length,
type: 'GET'
});
})).then(function(totalResultsArr) {
totalResultsArr.sort();
var countResultsArr = JSON.stringify(totalResultsArr);
return $.ajax({
url: 'updateSearchDb.php',
type: 'POST',
async: true,
dataType: 'text',
data: { 'countResultsArr': countResultsArr },
error: function(a, b, c) { alert(a+b+c); }
});
}).then(function(data) {
var resultsDiv = document.getElementById("search");
if(data == "NORECORD") {
resultsDiv.innerHTML = 'Updated failed. There was a problem with the database';
} else {
resultsDiv.innerHTML = 'Update was successful';
}
});
}
}).then(null, function() {
alert('Some unexpected error occured: ' + e);
});
});
This is how you do it in 2016 (ES7)
You can just use async/await.
$(document).ready(async() => {
try {
var data = await $.ajax({
url: 'getSearchSon.php',
type: 'POST',
async: true,
dataType: 'text'
/*data: { }, */
});
if (data == 'connection') {
alert("Problem with MySQL connection.");
} else {
var dataSent = data.split("|");
var search_criterias = JSON.parse(dataSent[0]);
var date_length = dataSent[1];
var divison_factor = dataSent[2];
var totalResultsArr = await Promise.all(
search_criterias.map(criteria => $.ajax({
url: "https://www.googleapis.com/customsearch/v1"
+ "?q=" + criteria
+ "&cx=005894674626506192190:j1zrf-as6vg"
+ "&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM"
+ "&dateRestrict=" + date_length,
type: 'GET'
}))
);
totalResultsArr.sort();
var countResultsArr = JSON.stringify(totalResultsArr);
var data2 = await $.ajax({
url: 'updateSearchDb.php',
type: 'POST',
async: true,
dataType: 'text',
data: { 'countResultsArr': countResultsArr },
error: function(a, b, c) { alert(a+b+c); }
});
if(data2 == "NORECORD") {
resultsDiv.innerHTML = 'Updated failed. There was a problem with the database';
} else {
resultsDiv.innerHTML = 'Update was successful';
}
}
} catch(e) {
alert('Some unexpected error occured: ' + e);
}
});
UPDATE 2016
Unfortunately the async/await proposal didn't make it to the ES7 specification ultimately, so it is still non-standard.
You could reformat your getTotalResults function in the following matter, it would then search rather sequential, but it should also do the trick in returning your results with an extra callback.
'use strict';
function getTotalResults(searchParam, callback) {
var url = "https://www.googleapis.com/customsearch/v1?q={param}&cx=005894674626506192190:j1zrf-as6vg&key=AIzaSyCanPMUPsyt3mXQd2GOhMZgD4l472jcDNM&dateRestrict=" + (new Date()).getTime(),
i = 0,
len = searchParam.length,
results = [],
req, nextRequest = function() {
console.log('received results for "' + searchParam[i] + '"');
if (++i < len) {
completeRequest(url.replace('{param}', searchParam[i]), results, nextRequest);
} else {
callback(results);
}
};
completeRequest(url.replace('{param}', searchParam[0]), results, nextRequest);
}
function completeRequest(url, resultArr, completedCallback) {
var req = new XMLHttpRequest();
req.open("GET", url, true);
req.onreadystatechange = function() {
if (this.readyState === 4 && this.status == 200) {
var totalResults = JSON.parse(this.responseText).queries.nextPage[0].totalResults;
resultArr.push(totalResults);
completedCallback();
}
};
req.send();
}
getTotalResults(['ford', 'volkswagen', 'citroen', 'renault', 'chrysler', 'dacia'], function(searchResults) {
console.log(searchResults.length + ' results found!', searchResults);
});
However, since you already use JQuery in your code, you could also construct all the requests, and then use the JQuery.when functionality, as explained in this question
Wait until all jQuery Ajax requests are done?
To get the callback execute after google calls are finished you could change:
var requestCounter = 0;
var helperFunc = function(arrayIndex)
{
return function()
{
if (arrXhr[arrayIndex].readyState === 4 && arrXhr[arrayIndex].status == 200)
{
requestCounter++;
totalResults = JSON.parse(arrXhr[arrayIndex].responseText).queries.nextPage[0].totalResults;
totalResultsArr.push(totalResults);
if (requestCounter === search_criterias.length) {
callbackFunction.apply(totalResultsArr);
}
}
}
}
then remove the setTimeout on searchCreteriaFuc.
Consider using promises and Promise.all to get all much cleaner :D
Hello everybody. I have a problem with my code. I use the jquery framework. When I want to call $.ajax(requestOptions), function xmlParser(xml) don't working.
I try to find a resolve this problem, but I can't nothing find.
$(document).ready(function () {
var requestOptions = {
type: "GET", //The method
url: "Course_Valute_02-07-2014.xml", //It is reference on xml file
dataType: "xml", //The type of data
crossDomain: true, //Allow to do the cross-domain request
success: xmlParser //Calling function
};
function xmlParser(xml) {
$("#load").fadeOut();
$(xml).find("Valute").each(function() {
$("#outputListValutes").append(
"<option value=" + $(this).find("CharCode").text() + ">" + $(this).find("CharCode").text() + "</option>");
});
};
$.ajax(requestOptions);
$("#clear").click(function() {
var sumValue = document.getElementById("sum").value = "";
var resValue = document.getElementById("result").value = "";
});
$("#convert").click(function(xml) {
//var selectCurrency = $("#inputListCurrency").val();
//findData(xml);
}(requestOptions));
function findData(xml) {
var decimalOnly = /^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/;
try{
var shortName = $("#outputListCurrency").val();
var value = $("#sum").val();
if(value == "") throw new Error("Empty value");
else if(!decimalOnly.test(value)) throw new Error("value must be of decimal digits");
else if(value < 0) throw new Error("Value isn't to be below zero");
else if(isNaN(parseFloat(value))) throw new Error("Value isn't to be as symbols");
$(xml).find("Valute").each(function() {
if(shortName == $(this).find("CharCode").text()) {
var nominal = $(this).find("Nominal").text();
var course = $(this).find("Value").text();
var result = parseFloat(value) * parseFloat(nominal) / parseFloat(course);
document.getElementById("result").value = Number(result).toFixed(2);
}
});
}
catch(e) {
alert(e);
}
}
});
change the success parameter of the request to use the xmlParser function (forgot () ):
var requestOptions = {
type: "GET", //The method
url: "Course_Valute_02-07-2014.xml", //It is reference on xml file
dataType: "xml", //The type of data
crossDomain: true, //Allow to do the cross-domain request
success: xmlParser(data) //Calling function
};
I found the solution this promlem. I am happy.
var courseFilePath = "xml/Course_Currency_02-07-2014.xml";
var listCurrency = [];
function insertOptions(){
for (var i = 0; i < listCurrency.length; ++i){
$("#outputListCurrency").append(
"<option value=" + listCurrency[i] + ">" + listCurrency[i] + "</option>");
}
}
function xmlParser(xml){
$("#load").fadeOut();
$(xml).find("Valute").each(function(){
var value = $(this).find("CharCode").text();
listCurrency.push(value);
});
listCurrency.sort();
};
function findData(xml){
var decimalOnly = /^\s*-?[0-9]\d*(\.\d{1,2})?\s*$/;
try {
var shortName = $("#outputListCurrency").val();
var value = $("#sum").val();
if (value == "") throw new Error("Empty value");
else if (!decimalOnly.test(value)) throw new Error("value must be of decimal digits");
else if (value < 0) throw new Error("Value isn't to be below zero");
else if (isNaN(parseFloat(value))) throw new Error("Value isn't to be as symbols");
$(xml).find("Valute").each(function(){
if (shortName == $(this).find("CharCode").text()){
var nominal = $(this).find("Nominal").text();
var course = $(this).find("Value").text();
var result = parseFloat(value) * parseFloat(nominal) / parseFloat(course);
document.getElementById("result").value = Number(result).toFixed(2);
}
});
}
catch (e){
alert(e);
}
}
$(document).ready(function(){
$.ajax({
type: "GET", //The method of sending for data
url: courseFilePath, //It is reference on xml file
dataType: "xml", //The type of data
success: function(xml){
xmlParser(xml);
insertOptions();
}
});
//insertOptions();
$("#clear").click(function() {
document.getElementById("sum").value = "";
document.getElementById("result").value = "";
});
$("#convert").click(function() {
var selectCurrency = $("#inputListCurrency").val();
$.get(courseFilePath, findData, "xml");
});
});
I have the following javascript and JsonResult. The issue I am having is the ajax post doesn't allow enough time for JsonResult to return the appropriate data. I probably don't completely understand javascript processing and I'm sure this is by design but I'm wondering how I can make this a synchronous request. In short, wait for the JsonResult action to complete before the javascript continues processing.
<script type="text/javascript">
$(document).ready(function () {
var table = document.getElementById("updateTable");
var tasks = new Array("shutdown", "prep", "boot", "ready");
var tasksLength = tasks.length;
for (var i in tasks) {
for (var loop = 1, max = table.rows.length; loop < max; loop++) {
id = table.rows[loop].cells[0].innerHTML;
task = tasks[i];
ImageUpdateStatus = {
ImageId: parseInt(id),
Task: task,
Status: "pending"
}
$.ajax({
type: "POST",
url: "UpdateStatus",
data: $.postify(ImageUpdateStatus),
success: function (data) {
var status = data.status;
}
});
ImageUpdateStatus.Status = status;
if (ImageUpdateStatus.Status == "success") {
task = task.concat(" ");
document.getElementById(task.concat(id)).src = "/PVSUtil_ver2/Assets/Images/Image.Success.png";
j = parseInt(i) + 1;
if (j < tasksLength) {
nextTask = tasks[j];
nextTask = nextTask.concat(" ");
document.getElementById(nextTask.concat(id)).src = "/PVSUtil_ver2/Assets/Images/Image.Load.gif";
}
}
}
}
document.getElementById('nextButton').className = "navigation";
document.getElementById('nextButton').disabled = false;
});
//
// GET: /Build/UpdateStatus
public JsonResult UpdateStatus(ImageUpdateStatus imageUpdateStatus, SessionStateItemCollection sessionItems = null)
{
var data = new object();
string status = null;
ImageInfo imageInfo = new ImageInfo();
IImageInfoServices svcImageInfo = new ImageInfoServicesRepository();
imageInfo = svcImageInfo.GetImageByImageId(imageUpdateStatus.ImageId);
IDeviceControlServices svcDevice = new DeviceControlServicesRespository();
IPVSCommandServices svcPVSCmds = new PVSCommandServicesRespository();
if (imageUpdateStatus.Task == "shutdown")
{
status = svcDevice.Shutdown(imageInfo.ImageId);
//status = "success";
data = new
{
status
};
}
if (imageUpdateStatus.Task == "prep")
{
List<UpdateReasonForm> updateReasonForms;
if (sessionItems.Keys.Count > 0)
{
updateReasonForms = sessionItems["UpdateReasonForms"] as List<UpdateReasonForm>;
}
else
{
updateReasonForms = Session["UpdateReasonForms"] as List<UpdateReasonForm>;
}
foreach (var item in updateReasonForms)
{
if (item.ImageId == imageInfo.ImageId)
{
status = svcPVSCmds.PrepImage(imageInfo, item.NewVersion);
}
}
data = new
{
status
};
}
if (imageUpdateStatus.Task == "boot")
{
status = svcDevice.Boot(imageInfo.ImageId);
data = new
{
status
};
}
if (imageUpdateStatus.Task == "ready")
{
status = "success";
data = new
{
status
};
}
return this.Json(data, JsonRequestBehavior.AllowGet);
}
Just move the code that relies on the result from the ajax request into the success callback function:
$.ajax({
type: "POST",
url: "UpdateStatus",
data: $.postify(ImageUpdateStatus),
success: function (data) {
ImageUpdateStatus.Status = data.status;
if (ImageUpdateStatus.Status == "success") {
task = task.concat(" ");
document.getElementById(task.concat(id)).src = "/PVSUtil_ver2/Assets/Images/Image.Success.png";
j = parseInt(i) + 1;
if (j < tasksLength) {
nextTask = tasks[j];
nextTask = nextTask.concat(" ");
document.getElementById(nextTask.concat(id)).src = "/PVSUtil_ver2/Assets/Images/Image.Load.gif";
}
}
}
});
You don't want to make the request synchronous; you want to put all code that depends on the result into your callback:
$.ajax({
type: "POST",
url: "UpdateStatus",
data: $.postify(ImageUpdateStatus),
success: function (data) {
var status = data.status;
ImageUpdateStatus.Status = status;
if (ImageUpdateStatus.Status == "success") {
task = task.concat(" ");
document.getElementById(task.concat(id)).src = "/PVSUtil_ver2/Assets/Images/Image.Success.png";
j = parseInt(i) + 1;
if (j < tasksLength) {
nextTask = tasks[j];
nextTask = nextTask.concat(" ");
document.getElementById(nextTask.concat(id)).src = "/PVSUtil_ver2/Assets/Images/Image.Load.gif";
}
}
}
});
$.ajax({
type: "POST",
async: false,
url: "UpdateStatus",
data: $.postify(ImageUpdateStatus),
success: function (data) {
var status = data.status;
}
});
but you really should avoid this, you should really look into making your application work with that wait for the ajax request
I really feel that you should aggregate any data you need to render your view for the first time on the server side and then push it down to the page. You could use JavaScript to do the rendering once the data is in the page (could be stored in JSON format in a hidden field) but I don't think it's optimal to have the page making an Ajax call when it's rendering for the first time.