Second Jquery json getting fired before first Jquery being complete - javascript

I have two javascript function which populate some data using jquery json. Both working fine but problem is that second function getting called before first one execute. My code is :
$(document).ready(function () {
loadSubject();
getTopic();
});
function loadSubject() {
var CourseId = document.getElementById('CourseId').value;
alert('22222');
jQuery.support.cors = true;
$.ajax({
url: 'http://220.45.89.129/api/LibraryApi',
type: 'Get',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: { DataType: 'Subject', UserRecId: 0, ParentId: CourseId },
dataType: 'json',
success: function (data) {
var subjectDivs = "";
var divs = "";
var i = 1;
$.each(data, function (index, value) {
divs = "";
// Some code here
i = i + 1;
});
subjectDivs = subjectDivs + divs;
alert('11111');
$('#cCount').val(i);
document.getElementById('accordion').innerHTML = subjectDivs;
},
error: function (e) {
alert(JSON.stringify(e));
}
});
}
function getTopic() {
var c = $('#cCount').val();
alert(c);
for (var i = 1; i <= c; i++) {
var subId = $('#hdn_' + i).val();
jQuery.support.cors = true;
$.ajax({
url: 'http://220.45.89.129/api/LibraryApi',
type: 'Get',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: { DataType: 'Topic', UserRecId: 0, ParentId: subId },
dataType: 'json',
success: function (data) {
var topicDivs = "";
var divs = "";
tDivs = '';
$.each(data, function (index, value) {
divs = '';
divs = '<div class="row">';
divs = divs + '<div class="subject">' + value.Name + '</div>';
divs = divs + "</div>";
topicDivs = topicDivs + divs;
});
$('#sDiv_' + i).html(topicDivs);
},
error: function (e) {
alert(JSON.stringify(e));
}
});
}
}

This is not the way how ajax get executes. If you put two jquery ajax requests one by one then they will execute in sequence by it is not necessary that second request will be executed after first request completes or response of first request is received.
If you want this to happen then there are two ways
1. Use async:'false'
This makes a request to wait until response is recieved before executing next statement in javascript.
What does "async: false" do in jQuery.ajax()?
2. Use callbacks
Write the second function which you want to execute in success or complete callback of your first ajax request.
jQuery ajax success callback function definition

Try adding return statement before $.ajax({}) within both loadSubject and getTopic , to return jQuery promise object , which can be handled at deferred.then
function loadSubject() {
return $.ajax()
}
function getTopic() {
return $.ajax()
}
loadSubject().then(getTopic);
function a() {
return new $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(1)
}, 2000)
}).promise().then(function(data) {
console.log(data)
})
}
function b() {
return new $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(2)
}, 2000)
}).promise().then(function(data) {
console.log(data)
})
}
a().then(b)

You have to add async:false in your first ajax request, it stop next execution till first ajax request will complete its execution.
So your first function like this
function loadSubject() {
var CourseId = document.getElementById('CourseId').value;
jQuery.support.cors = true;
$.ajax({
url: 'http://220.45.89.129/api/LibraryApi',
type: 'Get',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: { DataType: 'Subject', UserRecId: 0, ParentId: CourseId },
dataType: 'json',
async:false,
success: function (data) {
var subjectDivs = "";
var divs = "";
var i = 1;
$.each(data, function (index, value) {
divs = "";
// Some code here
i = i + 1;
});
subjectDivs = subjectDivs + divs;
alert('11111');
$('#cCount').val(i);
document.getElementById('accordion').innerHTML = subjectDivs;
},
error: function (e) {
alert(JSON.stringify(e));
}
});
}

Call second function from first ajax success function
$(document).ready(function () {
loadSubject();
});
function loadSubject() {
// code here
$.ajax({
url: 'http://220.45.89.129/api/LibraryApi',
type: 'Get',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: { DataType: 'Subject', UserRecId: 0, ParentId: CourseId },
dataType: 'json',
success: function (data) {
//code here
getTopic(); // Second function calling
},
error: function (e) {
alert(JSON.stringify(e));
}
});
}
Now when first function is executed successfully then second function will be called.

Related

properly queuing different ajax requests

I see a lot of solutions to queue ajax requests but I am trying to understand how to implement one for this case. Should it be a push and shift queue?:
var urlList = ['urlA', 'urlB', 'urlC', ...];
function initSession() {
for (var i = 0; i < urlList.length; i++) {
getResponse(urlList[i]); // this is what I would like to queue.
}
}
function getResponse(theURL) {
steps.shuffleLetters({
"text": messages[mesInd]
});
$.ajax({
method: 'GET',
url: theURL,
dataType: 'text',
success: function(data) {
setTimeout(function() {
steps.shuffleLetters({
"text": data
});
}, 1000);
mesInd = mesInd + 1;
},
error: function(data) {
setTimeout(function() {
steps.shuffleLetters({
"text": "Click Again!"
});
}, 1000);
mesInd = 0;
}
});
}
You can do that by removing the for loop and call the next url after the success of the current request
Check the code below:
var urlList = ['urlA','urlB','urlC',...];
var length = urlList.length;
var currentRequest = 0;
getResponse(urlList[currentRequest]);
function getResponse(theURL){
steps.shuffleLetters({"text": messages[mesInd]});
$.ajax({
method: 'GET',
url: theURL,
dataType: 'text',
success: function (data) {
setTimeout(function(){steps.shuffleLetters({"text": data});}, 1000);
//Here you will call the next request
currentRequest +=1;
if(currentRequest < length)
{
getResponse(urlList[currentRequest]);
}
mesInd = mesInd+1;
},
error: function (data) {
setTimeout(function(){steps.shuffleLetters({"text": "Click Again!"});}, 1000);
mesInd = 0;
}
});
}

Returning the correct promise in angular

I'm having trouble returning the correct promise for a service in angular.
this is my function:
postToSP.post($scope.sharePointURL, data).then(function() {
$scope.gettingData = false;
$scope.yammerListName = "Successfully posted to SP";
}).catch(function(e){
//console.log("Error: ", e);
$scope.yammerListName = "Sorry we couldn't post to that page, please make sure your column names are EXACTLY the same!"
$scope.gettingData = false;
throw e;
});
And this is my service, i get the error: "Unable to get property 'then' of undefined or null reference". I know it's because i'm not returning the promise properly but I can't figure out how to do it correctly. Please help, thanks in advance.
app.service("postToSP", function($http) {
//Submit to SP function
this.post = function(originalurl,data){
console.log(data);
var url = originalurl.split("Lists/")[0];
var listname = originalurl.split("Lists/")[1].split("/")[0];
//if the row is checked send it, if not jump to the next row
//run the function, continue until the end and break
var i = 0;
return letsPost(i);
function letsPost (i) { //i<data.length; i++
if (data[i].checked == false) {
i++;
return letsPost(i);
} else {
var formattedText = document.getElementById("text"+i).innerHTML.toString() ;
var formattedCreated = document.getElementById("created"+i).innerHTML.toString();
var formattedLikes = document.getElementById("likes"+i).innerHTML.toString();
var formattedLinks = document.getElementById("links"+i).innerHTML.toString();
var uploadData = { //change this for input data
'__metadata': { 'type': 'SP.Data.' + listname + 'ListItem' },
'Title': i + "",
'Likes': formattedLikes,
'Post_x0020_Date': formattedCreated,
'Post_x0020_Links' : formattedLinks,
'Post_x0020_Text': formattedText
};
console.log(uploadData);
createListItem(url, listname, uploadData)
.done(function (columnData) {
console.log('Added row' + i);
// if there is more data
if (i < data.length) {
i++;
return letsPost(i);
//add new data and continue the function
} else {
return;
}
})
.fail(function (error) {
console.log(JSON.stringify(error));
alert("Error:" + JSON.stringify(error));
throw error;
});
//Function to get form digest token
function getFormDigest(webUrl) {
return $.ajax({
url: webUrl + "/_api/contextinfo",
method: "POST",
headers: { "Accept": "application/json; odata=verbose" }
});
};
//Function to create the list item
function createListItem(webUrl, listName, itemProperties) {
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listName + "')/items",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
console.log(data.d.results);
},
error: function (data) {
console.log(data);
}
});
return getFormDigest(webUrl).then(function (data) {
return $.ajax({
url: webUrl + "/_api/web/lists/getbytitle('" + listName + "')/items",
type: "POST",
processData: false,
contentType: "application/json;odata=verbose",
data: JSON.stringify(itemProperties),
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": data.d.GetContextWebInformation.FormDigestValue
}
});
});
};
};
};
};
});
in your function declare the promise first
this.post = function(originalurl,data){
var deferred = $q.defer();
the data that you want to return use
deferred.resolve(dataToReturn)
and at the end of your function add
return deferred.promise;
From what I understand your code, mistake you are doing is you are returning the promise returned from getFormDigest but also applying then function on it and returning another promise. If you dont return getFormDigest nothing will be returned since its async.
To solve it you can use angular $q library and return and independent promise. Resolve that promise in your then function where you are returning a promise and no need to return getFormDigest so only one promise will be returned and hopefully your problem will be resolved.
In simple way you can achieve it..i hope it make sense
//in your controller
yourService.addData(yourPayload);
.then(function (cou) {
$scope.data = cou.data;
});
//in your service
this.addData = function (data) {
var response = $http({
method: "POST",
url: 'your url',
data: data,
dataType: "json"
});
return response;
}

How to combine multiple call to Ajax Data base from different JS files

I have some code on a file that makes Ajax calls. This file is being called as a function by multiple other files that creates a new instance each time.
This is the JS code that is being called:
define(["underscore", "homeop", "domReady!"],
function (_, homeop, domready) {
var timeout = 500;
return function (opUrl, opList, onCallback) {
// IRRELEVANT CODE
var getFetch = function (optionName) {
$.ajax({
url: optionsUrl,
data: { optionNames: [optionName] },
type: "POST",
dataType: "json",
async: false,
traditional: true,
success: function (data) {
_.each(data, function (optionData, optionName) {
if (homeop.globalCache[optionName] === null) {
homeop.globalCache[optionName] = optionData;
}
});
},
error: function (message) {
console.error(message.responseText);
}
});
};
self.getInfo = function (optionName) {
if (homeop.globalCache[optionName] === undefined) {
if (!_.contains(homeop.getOption(), optionName)) {
getFetch(optionName);
}
// MORE IRRELEVANT CODE GOES HERE
In other JS files, I call the get function; for example
var these = new getOptions(optionsUrl, optionsList, onLoadCallback);
var getOpt = these.get(OptionsUrl);
The problem is I am making multiple calls to the get information from the database causing multiple call to my JS file. Each new instance of the JS file will create a ajax call.
Is there a way to wait for all the calls to be done and then get data from the database? In other words how can I somehow combine all the call to my 'getOption.js'?
Thanks
Try this.. You can also implement queue in place of stack
var optionStack = [];
var isAvailable = true;
var getFetch = function (optionName) {
if(isAvailable){
isAvilable = false; // function not available now
}
else {
optionStack.push(optionName)
return;
}
$.ajax({
url: optionsUrl,
data: { optionNames: [optionName] },
type: "POST",
dataType: "json",
async: false,
traditional: true,
success: function (data) {
_.each(data, function (optionData, optionName) {
if (homeop.globalCache[optionName] === null) {
homeop.globalCache[optionName] = optionData;
}
});
},
error: function (message) {
console.error(message.responseText);
},
done: function (){
isAvailable = true;
if(optionStack.length > 0){
getFetch(optionStack.pop());
}
}
});
};

query clearInterval when variable is "x"

I have made a function that is controlling a row in a my database for a certain number with AJAX.
Im calling the function with a click function and putting the function in a setInterval function to make the check 10 times a second.
In the beginning it will return 0, but at some point (usually within 5 seconds) it will return something els than 0, when it does i want to clearInterval.
But im not sure how to this?
This is my function:
function get_buzzer() {
$.ajax({
url: 'ajax_buzzer.php',
dataType: 'json',
async: false,
type: 'post',
data: {
job: 'get'
},
success:function(s) {
if(s['number'] == 0) {
var player = false;
} else {
var player = true;
}
}, error:function(e) {
}
});
}
$(document).ready(function() {
$('#test').click(function() {
var buzzer = setInterval("get_buzzer()",100);
});
});
You can do something like
$(document).ready(function () {
//make buzzer a share variable
var buzzer;
$('#test').click(function () {
buzzer = setInterval(get_buzzer, 100);
});
function get_buzzer() {
$.ajax({
url: 'ajax_buzzer.php',
dataType: 'json',
async: false,
type: 'post',
data: {
job: 'get'
},
success: function (s) {
if (s['number'] != 0) {
//if number is not 0 then clear the interval
clearInterval(buzzer)
}
},
error: function (e) {}
});
}
});
Try this : declare global variable to store interval and call window.clearInterval in success call of ajax
var buzzer;
function get_buzzer() {
$.ajax({
url: 'ajax_buzzer.php',
dataType: 'json',
async: false,
type: 'post',
data: {
job: 'get'
},
success:function(s) {
if(s['number'] == 0) {
var player = false;
} else {
var player = true;
//clear interval
window.clearInterval(buzzer);
}
}, error:function(e) {
}
});
}
$(document).ready(function() {
$('#test').click(function() {
buzzer = setInterval("get_buzzer()",100);
});
});
Use:
inside success use: And make var buzzer Gloval var.
clearInterval(buzzer);
Refence
You just need to clear the interval in the success handler of ajax call over a condition.
success: function (s) {
if (s['number'] != 0) {
//if number is not 0 then clear the interval
clearInterval(buzzer)
}
},
error: function (e) {}

Receiving json via ajax asp.net

My variable data in function ShowFavorits is undefined even do that my ajax call do return a json string.
<script type="text/javascript">
$(document).ready(function () {
ShowFavorits();
function AjaxGet() {
var param = "{'_userID': '1337'}";
$.ajax({
type: "POST",
url: "/webservices/MinSide.asmx/GetFavorits",
data: param,
contentType: "application/json;",
dataType: "json",
success: function (data) {
if (data.hasOwnProperty("d")) {
return (data.d);
}
},
error: function (data) {
//error
}
});
}
function ShowFavorits() {
var data = AjaxGet();
$("#addedList").html(
$("#addedTemplate").render(data)
);
}
});
[WebMethod]
public string GetFavorits(string _userID)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = int.MaxValue;
string JsonData = string.Empty;
var db = new ModelDataContext();
var list = db.table.Where(x => x.userID == _userID).OrderBy(x=> x.TimePin).ToList();
JsonData = jss.Serialize(list);
return (JsonData);
}
Why cant i return the result from my ajax?
Hope someone can help me, have been stuck for hours now debugging this.
Thanks in advance.
The call to $.ajax in AjaxGet is asynchronous: the function returns undefined because the ajax call hasn't finished.
You should move the call to ShowFavourits into the ajax success function so that it executes once the ajax call is complete/successful
<script type="text/javascript">
$(document).ready(function () {
// Kick-off the ajax request
AjaxGet();
function AjaxGet() {
var param = {_userID: '1337'};
$.ajax({
type: "POST",
url: "/webservices/MinSide.asmx/GetFavorits",
data: param,
dataType: "json",
success: function (data) {
if (data.hasOwnProperty("d")) {
ShowFavorits(data.d); // Pass the data to the template
}
}
});
}
function ShowFavorits(data) {
$("#addedList").html(
$("#addedTemplate").render(data)
);
}
});

Categories