How to Save a MultiPerson PeoplePicker to a SharePoint List

In a recent project where I was building a SPFx webpart using React Hooks, Typescript, Fluent UI and PNPjs, I found myself struggling to save a multiperson peoplepicker to a SharePoint list. The biggest difficulty I was having was the fact that I needed to make a call to ensureUser to retrieve a user id for each person selected in the peoplepicker before I could save the group of users to the SharePoint list.

The ensureUser calls are async calls, which adds another layer of difficulty to this dilemma. At first glance, you might think, just loop through the users and make the call to ensureUser. Sure, that seems logical, except that leaves no way to wait for all of the calls to complete before moving on. In fact, when attempting this, I always ended up with an empty array in my peoplepicker, because the browser started each ensureUser call and immediately went on to saving the data before any of the ensureUser calls ever completed.

What I needed was a way to make multiple async calls and wait for all of them to be complete before I could move on to saving that data. Enter Promise.all, my prince riding in on a white horse! Promise.all is a promise that takes an array of promises and resolves when all of the promises have resolved or rejects when one of the promises is rejected. Sounds magical, doesn’t it?! Let’s see it in action:

const saveListItem = async => {
    let userIds = [];
    await Promise.all( (member) => {
        let userId = await sp.web.ensureUser(`​${member.secondaryText}`);
    let projectTeamId = {
        ‘results’: userIds,
        Status: selectedProject.Status,
        ProjectTeamId: projectTeamId,

So what is happening here? I have created a function called saveListItem. It is important to note that this is an async function and you will need to use await when calling this function if you need to wait for it to resolve before moving on to whatever you are doing after it. It would look like this:

await saveListItem();

Inside the saveListItem function, you will see the magical Promise.all. I’m using await as I want to wait for Promise.all to resolve before moving on the the next bit of code. Promise.all is passed an array (selectedProject.ProjectTeam) of users. I map over the array and call ensureUser for each user to retrieve the userId. The result of the ensureUser call is then pushed to the userIds array.

Once all of the ensureUser calls have resolved, then the Promise.all resolves. The userIds array can then be used in the projectTeamId array, which will then be used to update the peoplepicker of the item in the SharePoint list.

To read more about Promise.all, check out the MDN web docs or this great blog: All you need to know about Promise.all.


Choosing the Right Front End Tools

Rick HerrmannRecently, I had the opportunity to meet with a client that was in the process of deciding on a front-end technology for their dev team to use.  They already did quite a bit of research and formed some opinions about different technologies, and wanted to get our opinion about the way they evaluated their options. One point I made early on in our discussion was that there is no one “right” answer to the question of “which tool(s) should we use?”.   Continue reading “Choosing the Right Front End Tools”

Dynamically Populating Drop Downs in Different Browsers

Mike BerrymanI had an issue recently with a pretty standard form in Angular 2. The form had some required fields, one of which was a drop down / select field that wouldn’t populate with options until the user had made some selections earlier in the form. The submit button for the form was disabled until all required fields were filled in.

The issue arose when the client started testing the form in their environment. Despite completely filling out the form, the submit button would stay disabled. Obviously something was wrong.

Continue reading “Dynamically Populating Drop Downs in Different Browsers”