0

I'm using SharePoint Online (2013), but I'm rather new to SP and anything Microsoft.

In my JavaScript, I'm programatically populating a client-side PeoplePicker and having the Picker resolve the new entries.

// passed to function
userKeysAsString = 'i:0#.f|membership|user1@example.com;i:0#.f|membership|user2@example.com';


// inside function...
// get the picker, add user keys; second param false means picker will try to resolve users
var peoplePickerDivTopSpan = $('#' + ppName + '_TopSpan')[0].id;
var peoplePicker = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivTopSpan];
peoplePicker.AddUserKeys(userKeysAsString, false);

That works just fine. The problem is that the next line after the function call retrieves the data from the picker before the users have been resolved. Whereas I'm trying to get the users' names, etc., every property for the new users is, e.g., i:0#.f|membership|user1@example.com.

I have looked over many posts and articles over the last 5 hours and everything I can find is about how to call a function every time a user is resolved:

  • during initialization: schema['OnUserResolvedClientScript'] = 'MyPickerUserResolved';
  • after adding

    SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivTopSpan].OnUserResolvedClientScript = function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnUserResolvedClientScript');
    };`
    

None of these actually delay the execution of the next line, although it's possible that I'm missing something. I don't actually want to execute a function anyway, although I would execute some sort of dummy function if that solved the problem.

I also created a do-while to keep checking the users' Resolved properties until there were none set to false. But that just crashed the browsers.

var qtyUnresolvedPPEntities = 0;

do {
    qtyUnresolvedPPEntities = 0;
    var ppEntities = JSON.parse($('#' + ppName + '_TopSpan_HiddenInput').val());
    $.each(ppEntities, function (i, e) {
        if (e.Resolved == false) {
            qtyUnresolvedPPEntities++;
        }
    });
} while (qtyUnresolvedPPEntities > 0);

Sooo... Anyone know how to wait until all PeoplePicker users have been resolved before executing the next line (getting all users from the PeoplePicker)?

  • I don't see if your using the peoplePicker.GetAllUserKeys(); or peoplePicker.GetAllUserInfo(); both of these functions returns collections of resolved user info. Have you tried using those? – Robban1980 Apr 22 '15 at 2:09
  • I've updated the post to indicate the function call happening. GetAllUserInfo() at the end of the function didn't delay proceeding beyond the function call until users were resolved. GetAllUserInfo() to get the data after the function call still returned unresolved users. Likewise, GetAllUserKeys() didn't delay until resolution was complete. GetAllUserKeys() did give me correct user keys, but that was the one thing I was already getting. – Skip Apr 22 '15 at 3:00
0

So I read through your post again to make sure I understood it correctly. And your issue is not that the users are not resolved but the Async nature of resolution of users.

I would suggest that you think in another way on how to run the what you want to execute after all users are resolved. As I understand from your post you always know how many users will be resolved as the list of users come from a different part of your system. If you check the number of those users and use the OnUserResolvedClientScript to check how many users have been resolved or which of them. And if all are resolved call your code you want to execute after

SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerDivTopSpan].OnUserResolvedClientScript = function (peoplePickerId, selectedUsersInfo) {
        // Check that all users have been resolved
    if(allResolved) {
    // call function that does stuff after all users resolved.
    }
};

This event to check if all users have been resolved and then call the code you want to execute after all users have been resolved from here. the OnUserResolvedClientScript should trigger every time a user is resolved.

One Alternative is that you let your "next line of code" handle the checking if all users are resolved and if not then it just don't execute whatever might be there.

Would this be an option?

  • The alternative to not do what comes next if the users aren't resolved isn't an option - gotta do it. I will definitely be looking at your other suggestion ASAP, though - sounds promising. – Skip Apr 22 '15 at 14:22
  • So, if I'm adding three users to the PeoplePicker and immediately after that I place the code you mentioned, OnUserResolvedClientScript, that's going to fire with every user resolution? It won't fire once on the first resolution, skip what's inside if(allResolved) because the other two aren't resolved yet, and then just move on to whatever comes next? – Skip Apr 22 '15 at 14:29
  • Yes! OnUserResolvedClientScript, after setting the PP, does fire multiple times so that I can hold off grabbing the data until it's actually there. Thank you so much for your assistance! (Forgive my delayed response - meetings, y'know :) – Skip Apr 22 '15 at 19:44
  • Great to hear the it worked out. :) – Robban1980 Apr 23 '15 at 2:05
0

My be you can use setTimeOut but this doesn't guarantee that users may have been resolved

setTimeout(function() {
      // Do something after 5 seconds
}, 5000);

You may want to have a look at Jquery Deffered Objects this waits until the code is executed and you can synchronise the behaviour of JS

  • Thank you so much for your assistance! It was good for me to learn more about jQuery deferred objects. – Skip Apr 22 '15 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.