I have a custom angular JS form for my list in a SP hosted app and i am facing a challenge when i need to set the user field value due to JS async been... out of sync. So specifically when the user clicks the save button i must;
- Get Values from people picker - work ok
- Ensure User (because they might have never accessed the site) - if the user is not the current user then the ID isnt returned
- Create list item setting the users as value to a user field - user objects not processed yet when the list item create code is executed
When the following code completes usually there are no users in the field, or if there are, its just one.
$scope.saveEvent = function () {
if ($scope.event.inviteOnly === 1) {
var peoplePicker = window.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
var usersVal = peoplePicker.GetAllUserInfo();
for (var i = 0; i < usersVal.length; i++) {
var ctx = SP.ClientContext.get_current();
var usr = ctx.get_web().ensureUser(usersVal[i].Key);
ctx.load(usr,'Include(ID)');
ctx.executeQueryAsync(function () {
var val = new SP.FieldUserValue();
val.set_lookupId(usr.get_id());
$scope.event.attendees.push(val);
}),
function () {
console.log("failed to resolve user");
}
}
if ($scope.event.attendees.length == usersVal.length) {
$scope.createListItem();
}
}
$scope.createListItem = function () {
var context = SP.ClientContext.get_current();
var targetList = context.get_web().get_lists().getByTitle("Events");
var itemCreate = new SP.ListItemCreationInformation();
var newItem = targetList.addItem(itemCreate);
newItem.set_item('Title', $scope.event.title);
newItem.set_item('EventDate', new Date($scope.event.date));
newItem.set_item('EventDepartment', $scope.event.department);
newItem.set_item('EventLocation', $scope.event.location);
newItem.set_item('EventOtherInfo', $scope.event.otherInfo);
newItem.set_item('EventTravelInfo', $scope.event.travelInfo);
newItem.set_item('EventType', $scope.event.eventType);
newItem.set_item('EventDescription', $scope.event.description);
newItem.set_item('EventRegistrationRequired', $scope.event.inviteOnly);
newItem.set_item('EventAttendees', $scope.event.attendees);
newItem.set_item('EventPicture', $scope.event.picture);
var questionHtml = '<ul>';
for (var i = 0; i < $scope.event.questions.length; i++) {
questionHtml += '<li>' + $scope.event.questions[i].value + '</li>';
}
questionHtml += '</ul>';
newItem.set_item('EventQuestions', questionHtml);
newItem.update();
context.load(newItem);
context.executeQueryAsync(function () {
if ($scope.event.inviteOnly == 1 && $scope.event.attendees && $scope.event.attendees.length > 0) {
newItem.breakRoleInheritance(false);
for (var j = 0; j < $scope.event.attendees.length; j++) {
var user = context.get_web()
.get_siteUsers()
.getById($scope.event.attendees[j].get_lookupId());
context.load(user);
var collRoleDefinitionBinding = SP.RoleDefinitionBindingCollection.newObject(context);
collRoleDefinitionBinding.add(context.get_web()
.get_roleDefinitions()
.getByType(SP.RoleType.reader));
newItem.get_roleAssignments().add(user, collRoleDefinitionBinding);
}
context.load(newItem);
context.executeQueryAsync(null, null);
}
},
function (sender, args) {
alert("Failed to save event: " + args.get_message());
});
}
}