Solved

jQuery aJax Disable Async

Posted on 2016-11-05
24
44 Views
Last Modified: 2016-11-07
I have a JavaScript which using jQuery accumulates a list of user emails.  In a loop,  I am resolving the emails to the SharePoint user ID.  The function works, but as I am in a loop trying to accumulate these IDs and the Ajax call is asynchronous, I don't get back the value while looping.  So,  I have tried to turn off async by setting the call parameter to async:false.  This doesn't work.

Any suggestions on this would be appreciated.
0
Comment
Question by:hbash
  • 12
  • 9
  • 3
24 Comments
 
LVL 82

Expert Comment

by:leakim971
ID: 41875797
This expert suggested creating a Gigs project.
it's not a good practice to disable async process at least on client side because it freeze the browser on most of case.
you can play with an FIFO array to go over your issue.
please post some code to have more help if needed
0
 
LVL 1

Author Comment

by:hbash
ID: 41875810
//A loop
for (i=0; i<splitpeeps.length; i++) {
						var useremail = splitpeeps[i];
						cnt=0;
						var i = GetUserId(useremail);									
						var currentUserID = i;
						acc = currentUserID + ", " + acc;
					}


//---------------------------------------------------------------------------------------------
function GetUserId(userName) {
	/// change this prefix according to the environment. 
	/// In below sample, windows authentication is considered.
	var prefix = "i:0#.f|membership|";
	/// get the site url
	var siteUrl = _spPageContextInfo.siteAbsoluteUrl;
	/// add prefix, this needs to be changed based on scenario
	var accountName = prefix + userName;
	
	/// make an ajax call to get the site user
	$.ajax({
		url: siteUrl + "/_api/web/siteusers(@v)?@v='" + 
			encodeURIComponent(accountName) + "'",
			async: false,
		method: "GET",
		headers: { "Accept": "application/json; odata=verbose" },
		success: function (data) {
			///popup user id received from site users.
			alert("Received UserId: " + data.d.Id);
			//alert(JSON.stringify(data));
			return data.d.Id;
		},
		error: function (data) {
			alert(JSON.stringify(data));
			return -1;
		}
	});
}

Open in new window

0
 
LVL 82

Expert Comment

by:leakim971
ID: 41875830
something like :
var i =0;
var acc = "";

var doItAsync = function(currentUserID) {
    if(currentUserID)
           acc = currentUserID + ", " + acc;
    if(splitpeeps[i]) {
           var useremail = splitpeeps[i];
	   GetUserId(useremail);
           i++;
    }
}

doItAsync();

//---------------------------------------------------------------------------------------------
function GetUserId(userName) {
	/// change this prefix according to the environment. 
	/// In below sample, windows authentication is considered.
	var prefix = "i:0#.f|membership|";
	/// get the site url
	var siteUrl = _spPageContextInfo.siteAbsoluteUrl;
	/// add prefix, this needs to be changed based on scenario
	var accountName = prefix + userName;
	
	/// make an ajax call to get the site user
	$.ajax({
		url: siteUrl + "/_api/web/siteusers(@v)?@v='" + 
			encodeURIComponent(accountName) + "'",
			async: false,
		method: "GET",
		headers: { "Accept": "application/json; odata=verbose" },
		success: function (data) {
			///popup user id received from site users.
			alert("Received UserId: " + data.d.Id);
			//alert(JSON.stringify(data));
			doItAsync(data.d.Id);
		},
		error: function (data) {
			alert(JSON.stringify(data));
			return -1;
		}
	});
}

Open in new window

0
 
LVL 1

Author Comment

by:hbash
ID: 41875832
I don't see the loop part.  How do I use this in the looping through the array of splitPeeps, which is an array of email addresses?
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41875833
no loop, each time the ajax call is ended, it call the doItAsync to see if there is more work/call to do
0
 
LVL 1

Author Comment

by:hbash
ID: 41875856
I'm not quite getting this.  Suppose I have a
function SaveMyIDs() {
  var splitpeeps={'person1@someplace.com', 'person2@someplace.com', 'person3@someplace.com', 'person4@someplace.com'};

 //Call the async / sync function and when done
acc = "comma delimated IDs";

//now save them
$('.someplace').attr('mypeeps', acc);

}

Open in new window



How do I use your structure to do that?
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41875886
Why loop on the client - why not send criteria to server and have it generate a list and send that back?
0
 
LVL 82

Accepted Solution

by:
leakim971 earned 500 total points
ID: 41876052
function SaveMyIDs() {

	window.splitpeeps = ['person1@someplace.com', 'person2@someplace.com', 'person3@someplace.com', 'person4@someplace.com'];
	window.splitpeepsPtr = 0;
	window.acc = "";

	//Call the async / sync function and when done
	doItAsync();

	// you can put an overlay on the screen to let 
	// the user know you're processing something
	// a div.pleaseWaitMessage over the screen with an image inside like this one :
	// http://www.kasc.ac.in/images/please_wait.gif
	$(".pleaseWaitMessage").show(); 

}

var part2 = function() {
	//now save them
	$('.someplace').attr('mypeeps', window.acc);
}


var doItAsync = function(currentUserID) {
    if(currentUserID)
    	if(window.acc)
	    	window.acc = currentUserID + ", " + window.acc;
    	else
	    	window.acc = currentUserID;
	if(window.splitpeeps[window.splitpeepsPtr]) {
		var useremail = window.splitpeeps[window.splitpeepsPtr];
		GetUserId(useremail);
		window.splitpeepsPtr++;
    }
    else {
    	// we done, we remove the overlay
    	$(".pleaseWaitMessage").hide();
    	// and run part 2 
    	part2();
    }
}

//---------------------------------------------------------------------------------------------
function GetUserId(userName) {
	/// change this prefix according to the environment. 
	/// In below sample, windows authentication is considered.
	var prefix = "i:0#.f|membership|";
	/// get the site url
	var siteUrl = _spPageContextInfo.siteAbsoluteUrl;
	/// add prefix, this needs to be changed based on scenario
	var accountName = prefix + userName;
	
	/// make an ajax call to get the site user
	$.ajax({
		url: siteUrl + "/_api/web/siteusers(@v)?@v='" +  encodeURIComponent(accountName) + "'",
		async: false,
		method: "GET",
		headers: { "Accept": "application/json; odata=verbose" },
		success: function (data) {
			doItAsync(data.d.Id);
		},
		error: function (data) {
			alert(JSON.stringify(data));
			return -1;
		}
	});
}

Open in new window


We can avoid to use window which set your variables global but this is a different story...
0
 
LVL 1

Author Comment

by:hbash
ID: 41876143
Can I use this instead of window?
0
 
LVL 1

Author Comment

by:hbash
ID: 41876166
I thought using this will create global variable also.
What is the difference between using this and window?
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41876168
instead going to far on new question, could you try and confirm the code work as you want ?
after that, you going to have all the leisure to do change on the code
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41876174
Still don't understand why you don't just send the whole list to a Service and have it build a return list of emails - you don't need a synch function for that - simply process the return in the Success call back.
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 1

Author Comment

by:hbash
ID: 41876177
The service only takes one parameter which is the email address.

I'm not aware of an alternate method that would take an array and return an array of results.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41876355
Can you not write your own service that takes an array and then calls the other service?

Not really the best solution looping on the client - for two reasons

1. The problem you are having now
2. Performance - every single request requires all the overhead of setting up a connection, constructing headers etc - all of that would be done once if you did it in one call.

I would seriously investigate the option of building a custom service that takes the array of emails and returns an array of id's.

I am not familiar enough with Sharepoint to say how this could be done but I do know you can write your own services that you can call - just can't tell you how to do it.
0
 
LVL 1

Author Comment

by:hbash
ID: 41876356
Not with with SharePoint Online.  It is possible to simulate, but not consided a best practice.
0
 
LVL 1

Author Comment

by:hbash
ID: 41876497
As I had thought on a SharePoint ASPX page,  you cannot use "windows".  So again the question, what is the difference between using windows and this?
Windows Erro
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41876500
oups...just remove the "s"... that should be "window" and not "windows"
window. set the variable global, it's not a problem with a small project.
0
 
LVL 1

Author Closing Comment

by:hbash
ID: 41876514
Very nice.  The only change that I had to make which leekim971 may have overlooked is to remove the setting async to false.  The server wasn't happy with that setting.  Once I removed it, the code ran just right.  

Great help.  Thank you.
1
 
LVL 1

Author Comment

by:hbash
ID: 41877113
Hi,
I know I accepted the proposed solution, but I am seeing that if there is only one ID in the array of peeps, the solution fails.

Any thoughts?

Thanks.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41877126
Check browser console and report any error
0
 
LVL 1

Author Comment

by:hbash
ID: 41877143
Two errors:
DOM7011: The code on this page disabled back and forward caching.  For more information see http://go.microsoft.com/fwlink/?LinkID=291337

Script5007: Unable to get property 'z' of undefined or null reference
CorePrimeShellG2Bundle.js (16,23535)
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41877274
Please post CorePrimeShellG2Bundle.js
0
 
LVL 1

Author Comment

by:hbash
ID: 41877295
I think that that module is part of SharePoint Online.  As such I don't have access to the hive and cannot provide it.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 41877427
here a test page with only one email. it work fine
https://jsfiddle.net/apzes7bj/

function SaveMyIDs() {

	window.splitpeeps = ['person1@someplace.com'];
	window.splitpeepsPtr = 0;
	window.acc = "";

	//Call the async / sync function and when done
	doItAsync();

	// you can put an overlay on the screen to let 
	// the user know you're processing something
	// a div.pleaseWaitMessage over the screen with an image inside like this one :
	// http://www.kasc.ac.in/images/please_wait.gif
	$(".pleaseWaitMessage").show(); 

}

var part2 = function() {
	//now save them
//	$('.someplace').attr('mypeeps', window.acc);
	$('.someplace').text(window.acc); // for debugging purpose
}


var doItAsync = function(currentUserID) {
    if(currentUserID)
    	if(window.acc)
	    	window.acc = currentUserID + ", " + window.acc;
    	else
	    	window.acc = currentUserID;
	if(window.splitpeeps[window.splitpeepsPtr]) {
		var useremail = window.splitpeeps[window.splitpeepsPtr];
		GetUserId(useremail);
		window.splitpeepsPtr++;
    }
    else {
    	// we done, we remove the overlay
    	$(".pleaseWaitMessage").hide();
    	// and run part 2 
    	part2();
    }
}

//---------------------------------------------------------------------------------------------
function GetUserId(userName) {
	/// change this prefix according to the environment. 
	/// In below sample, windows authentication is considered.
	var prefix = "i:0#.f|membership|";
	/// get the site url
	var siteUrl = _spPageContextInfo.siteAbsoluteUrl;
	/// add prefix, this needs to be changed based on scenario
	var accountName = prefix + userName;
	
	/// make an ajax call to get the site user
/*	$.ajax({
		url: siteUrl + "/_api/web/siteusers(@v)?@v='" +  encodeURIComponent(accountName) + "'",
		async: false,
		method: "GET",
		headers: { "Accept": "application/json; odata=verbose" },
		success: function (data) {*/
  setTimeout(function() { // fake ajax call
  		var data = { d: { Id: (Math.random()*10).toFixed(0) } }; // we return a random number
			doItAsync(data.d.Id);  
  },4000);
/*		},
		error: function (data) {
			alert(JSON.stringify(data));
			return -1;
		}
	});*/
}

var _spPageContextInfo = { siteAbsoluteUrl:"http://www.foo.com" };
jQuery(function() {
	SaveMyIDs();
})

Open in new window

0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Introduction Got endorsements from your clients?  Great!  There is almost nothing better than word-of-mouth advertising.  But how can you do that on the internet?  Sure you can make a page for endorsement quotations and list them all, but who is …
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now