UI won't update when making several SPSpervices calls

Aug 29, 2012 at 3:23 PM
Edited Aug 29, 2012 at 3:24 PM

I'm creating a tasking application that allows a user to create a parent task and then select from a list of retail locations to assign the task to. A 'child' task assignment is created in a list for each location that contains the ID of the 'parent' task. To accomplish this, I'm using a $.each() to iterate over the array of user selections and firing off a SPServices call for each to create that location's task.

Since this process can take a few seconds (the user could select up to about 70 stores), I want to provide some feedback. But, I haven't been able to get ANY UI element to update itself while that process is running, in either Chrome or IE8 (which is what most people in our company are using). So far I've tried:

  • An animated .gif - it doesn't actually animate
  • Spin.js to simulate a .gif - same problem, doesn't move
  • A jQueryUI progress bar that I update at the end of each iteration through the $.each() to reflect the total progress. Though I can verify that the value update is taking effect via debugging, the screen itself doesn't actually update to reflect the change.

So, I'm kind of at a loss as to where to go from here. Anyone else ever tried anything like this? Any ideas as to how to "force" the page to redraw at the end of each iteration?

(Also, I should note that I've read some of the other threads that deal with using a spinner and seen Marc's suggested solution of injecting the spinner into the html of an element and attaching the SPS call to that, but I don't think that will work since I'm calling SPS multiple times.)

Thanks much!

Aug 29, 2012 at 4:55 PM
Edited Aug 29, 2012 at 5:28 PM

What you really need to do is setup a callback. 

Prior to your $.each() iteration, you'll drop the spinner onto the page, then iterate, then fire your callback.  This is the only way to ensure the correct processing of your function calls.

Since you want the page to "redraw" after each SPS call, you'll want to handle your $.each() differently and add a callback within your SPService call or within the $.each() function itself.  Please note, no matter what you do, once you've made 2 concurrent ajax requests (async or synchronous), the IE browser will lock up until these are processed.

Some more info on the topic:

http://stackoverflow.com/questions/561046/how-many-concurrent-ajax-xmlhttprequest-requests-are-allowed-in-popular-browse

What I've gathered from your post is that you have a list for each store, which is why you are making so many SPService calls.  Why not put all of those items into one list as content types and create one batch for them all, thus creating one ajax request?

Cheers,
Matt 

Aug 29, 2012 at 5:59 PM

I've tried callbacks a few different ways, even combined with some setTimeouts to force some brief pauses, with no luck. What action would you suggest be taken by the callback?

So, no matter what I do with IE, it'll freeze after 2 requests? Even if they're not async and the UI update happens in between reqeusts?

Nope, all of the 'child' tasks live in the same list, so everything's going to the same place. Is there a way to batch create list items through one request?

Thanks for the assist!

Kyle

Aug 29, 2012 at 6:10 PM

Absolutely there is a way to batch your request and is the recommended method of doing so. ;-)

"So, no matter what I do with IE, it'll freeze after 2 requests? Even if they're not async and the UI update happens in between reqeusts?" --> Yep... It's the nature of the beast.

The documentation for the web service shows you how to setup a batch:

http://msdn.microsoft.com/en-us/library/lists.lists.updatelistitems.aspx

My roboCAML project makes it easy to create batches/CAML, if you wanted to give that a whirl...  Feel free to post your code if you get stuck.

Cheers,
Matt 

Aug 29, 2012 at 6:10 PM
Can you share the code that you believe is causing this?
Usually, in IE, the heavy manipulation of DOM elements will cause the UI to "freeze"... specially inserts and deletions into DOM...
I also assume that you have async input parameter to SPServices calls set to True... if not, then yes, each one of those calls will "block" the UI until they complete.

So as a highlevel design approach, you want to 1) do the calls to the server in async, 2) as Matt suggested, use the callback to update status on the UI

Now, even this may not work, because it sounds like you are firing them all in parallel. The responses may be cumming back to so fast that the UI does not get a chance to update itself. Looking at your code implementation may help give you better direction. Another approach I have used in the past is to build up a batch update with javascript and then issue less calls to the server (ex. each call to UpdateList created 50 items)... you could further build a queue (an array of updates) and execute them all in sequence rather than in parallel.

Just

_________
Paul T


Aug 29, 2012 at 6:52 PM

Awesome, I had no idea batch updates were that flexible. That's definitely the way to go then - I'll do some refactoring and give it another shot!