Sunday, 3 February 2013

SharePoint 2013: Working with User Profiles & JavaScript CSOM

SharePoint 2013 has added a variety of functionality to the Client API. One of them is the ability to fetch User Profile data. Now you can directly query the user profiles and get the required data from the client site. This can be really useful if you are building apps.

If you want to use the REST API to work with user profiles, please see one of my other posts: http://www.vrdmn.com/2013/07/sharepoint-2013-get-userprofile.html

In this post, I will show you how to work with User Profiles using the JavaScript Client Object Model

Before we get started with the code, lets make couple of things sure. First,  you will need a reference to the following JavaScript files in your page:


(jQuery is not required but I have added it because we will need it for the $.ajax function when doing REST queries)

Second thing, you will need the domain\username of the user you want to get the user profile data for. This can be easy to get if you are in an On-Prem environment. But if you are working with SharePoint Online, this can be quite tricky. Your username might not always be in the domain\username format. It is stored in the LoginName property if you are querying the Site User Information List:

https://yoursite.sharepoint.com/sites/pubsite/_api/Web/GetUserById(17)

and it is stored in the AccountName property if your querying the User Profile Service:

https://yoursite.sharepoint.com/sites/pubsite/_api/SP.UserProfiles.PeopleManager/GetMyProperties

In SharePoint Online, it will most probably be in the following format:

i:0#.f|membership|vardhaman@yoursite.onmicrosoft.com


Quick Note: If you are using the REST API, you will need to encode the username before you use it in your call. The encodeURIComponent( ) function can be helpful here.

Enough talking. Lets jump into some code right away:

1) Get Multiple User Profile Properties:



2) Get Single User Profile Property:



3) Get User Profile Properties of the Current User:



4) Get Properties of Multiple Users in Single Request:



For this last example, Let's observe the XML which is sent to the server:



With this, we can confirm that only one call was made to the server to retrieve the properties of multiple users. This way, you can even retrieve multiple properties of multiple users in one call.

42 comments:

sagar2610 said...

Very well written. I want to get user profile properties for all the users and not for a specific user. I am not able to find a way to get properties for all the users. Please a suggest a way. I am working on an on-premise environment.

Vardhaman Deshpande said...

Unfortunately, the only way of getting properties of all the users is by using Server Side code. Since you are on on-premise environment, you might be able to use it. Here is a helpful link:
http://msdn.microsoft.com/en-us/library/jj163800.aspx

Anonymous said...

Hi Vardhaman. This is an Awesome post. Congratulations.
I have a question about how to get the current user instead of "hardcode" the name of the user as domain\username. How do I get the current user?
Thank you

Vardhaman Deshpande said...

For getting the current user's properties, you don't need to use the username. You can directly get the properties by using the peopleManager.getMyProperties() method.

Vardhaman Deshpande said...

I have updated the blog with the code to get the current users profile properties.

Anonymous said...

Thank you for taking the time to write about this so thoroughly and giving code examples. Been trying to find reliable information all week and this is by far the most straight forward answers :)

Anonymous said...

Vardhaman,

I want to display the user one by one, i mean not as a list. user information. how to apply your code to achieve this.

Mike Hudson said...

Hello

Firstly, thanks for taking the time to post the code. I wondered if you could help me, I am trying to use the code in an AppPart inside a Sharepoint.com hosted site. However, upon running the code I get the following error:

Error: Access denied. You do not have permission to perform this action or access this resource.

My code is below:


(function ($) {

$(document).ready(function () {
// Ensure that the SP.UserProfiles.js file is loaded before the custom code runs.
SP.SOD.executeOrDelayUntilScriptLoaded(loadUserData, 'SP.UserProfiles.js');
});

var userProfileProperties;

function loadUserData() {

//Get Current Context
var clientContext = new SP.ClientContext.get_current();

//Get Instance of People Manager Class
var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

//Get properties of the current user
userProfileProperties = peopleManager.getMyProperties()

clientContext.load(userProfileProperties);

//Execute the Query.
clientContext.executeQueryAsync(onSuccess, onFail);

}

function onSuccess() {

$('#message').text(userProfileProperties.get_displayName());

}

function onFail(sender, args) {
alert("Error: " + args.get_message());
}

})(jQuery);



Have you any ideas how I can work around this?

Max said...

@sagar2610 & @Vardhaman Deshpande

there is a workarround to obtain all userprofiles without server side code. Just use the search REST service - for example:
_api/search/query?querytext='*'&selectproperties='AccountName'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'
if your searchservice is configured properly, this should work. Regards

Vardhaman Deshpande said...

@Max,
Yes you are right you can use search to get all the usernames and then get properties of all users using the User Profile Service.

Unfortunately there is no way to iterate all the users using the User Profile Service Only.

Vardhaman Deshpande said...

@Mike Hudson

This seems like a permission issue to me. Make sure that the user with which you are making the JS call has enough permissions to access the User Profile Service.

Mike Hudson said...

Thanks - you was right in some respects. I had not yet set the values in the AppManifest to allow 'read' of the properties.

Thanks for your help.

manoranjan mohapatra said...

first of all thanks Vardhman, its a nicely written / explained post.

@Mike Hudson, I was also facing the same issue, in my case the cause was the app manifest file, I have not provided permissions to user profiles there, added read permission to user profiles and the issue is resolved

Kourosh said...

Hi and thanks for this useful post. I have a Problem and I thought maybe you can help me.
How can I retrieve the resent blog posts of a user (my sites located on another Web Application) from his/her Blog by using REST? thanks again

Vardhaman Deshpande said...

Hi Kourosh,

You will have to use server side code to get the recent blog posts.

Mike Hudson said...

Hi Vardhaman

Thanks for your help so far, I wonder if you could help me one last time.

I am really struggling on something that should be so simple..

Slightly embarrassing, but I am struggling to retrieve the managers name, email address and telephone number for the currently logged on user. I've tried all manor of combinations of the code.

Is there any chance you could help out at all?

Cheers

Vardhaman Deshpande said...

Hi Mike,
Yes you can easily do that. I will show how to do it using the REST API:

"http://SiteName/_api/SP.UserProfiles.PeopleManager/GetMyProperties/ExtendedManagers"

Weird thing is I get the correct value using the REST API, but if I use the Client Object Model, I get a blank value. Need to check on that.

Peter Michael said...

Mike any ideas why I can't get the Manager user property to return any data?

http:///_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertyFor(accountName=@v,propertyName='Department')?@v='ke\'

If I plug in Department, Last Name, email, etc.. Data is returned.

Jason said...

Hi Vardhaman,

Excellent blog post but I'm having some problems using some of this code in an item's NewForm page.

I'm trying to read the current user's Manager information from UPS and I can't get your Example 3 to work.

For some reason the SP.UPS.js file won't load.

My code is really simple now because I'm trying to get the code to work.

The alert never fires because, I guess the SP.UPS.js file is never loaded.

Is there some restriction on using the UPS Service on a New Form


--- javascript

SP.SOD.executeOrDelayUntilScriptLoaded(TestUPS, "SP.UserProfiles.js");

var userProfileProperties;

function TestUPS() {
alert("UPS is loaded");
}

---- end javascript

Stephen Davidson said...

I have this working, I've simply added the code into my master page...however I have noticed that sometime i'm not getting permission to display the user image. The only way to fix is to visit the "my" site which displays the image then back to the main site and it will work again?!

If this is a user permission issue then i'm not sure what kind of permission's i need to give them...anyone done this?

Mike Hudson said...

Thanks Vardhaman

This is what I ended up using... get current sharepoint user manager-details using javascript

Sure there's an easier way - but for now, it does the trick.

Thanks for all your help so far!

Vardhaman Deshpande said...

@Jason. If you are working on a NewForm, then you will have to add the "_layouts/15/SP.UserProfiles.js" file to page and then call the ExecuteOrDelayUntilScriptLoaded function. Or you can use the jQuery.getScript function. See some of my other posts for how to load scripts with jQuery.getScript

Christopher said...

Thank you for this great post. Is it possible to get multiple properties for multiple users in a single request? I tried to adapt your code without success.

Vardhaman Deshpande said...

Hi Christopher,

That should be possible by combining code from code-snippets 1 and 4.

Can you post your code as a question on http://sharepoint.stackexchange.com/ and let me know. I can take a look at it.

kaviya Balasubramanian said...

Hi Vardhaman,

Thanks for your post. your code is working fine for me, But if the user has no image in user profile property? how can i set the default image ?

Thanks in advance.

Clem said...

In SP2010, there is no PeopleManager object

Vardhaman Deshpande said...

@Clem

Yes the PeopleManager class is part of the SharePoint 2013 Client API

Pavan Teja Ambisetty said...

Great Post. I have been trying to autopopulate user details based on the entry in peoplepicker field but failed. I am a beginner in JS and I could use some help. Thanks in advance!

Shafaqat Ali said...

I can get all properties but "QuickLinks" is empty, any idea why?

Patrick Burke said...

When I attempt to run, I get the following errors:
SCRIPT5007: The value of the property 'NotifyScriptLoadedAndExecuteWaitingJobs' is null or undefined, not a Function object
SP.UserProfiles.js, line 1 character 140515

SCRIPT5007: Unable to get value of the property 'ExecuteOrDelayUntilScriptLoaded': object is null or undefined
WhoamI.html, line 11 character 2

Vardhaman Deshpande said...

Hi Patrick you seem to be calling the code from a standalone html page. This code will only run in a SharePoint page with a SharePoint context

avala chiranjeevi said...

Hi Vardhaman .this is awesome post ...congratulations.
I have a question I need to display site owners of every site with image in home page of every site ..can u pls provide some useful guideance how to achieve it

Vardhaman Deshpande said...

Hi avala chiranjeevi,

You can get the site owners from the Site Owners group which can be found Web.get_associatedOwnerGroup() from JSOM. Then using the code in this blog post, get the images of each user.

Praveen Battula said...

Hello,
Is there any way we can identify or know the code runs in On-Premmise or SharePoint Online?

ryan byrd said...

In order to get profile properties for *all users* you could query the user information list to create a list of user accounts and use that to query the user profile service.

WikiChow said...

This is a excellent post and it has me 1/2 way to the goal. I am trying to retrieve the employeeID from user profiles to merge with a URL. Any idea how to do this?

shekar said...

Hi Vardhaman,

Thanks for this post. Its really working fine.

Only one thing I want is I want to get user data only for first page load.

But using this on subsequent edit and view mode also I am getting user data.

Please let me know if we can get user data only on first page load of the List/Library/Tasks list.

Any help would be appreciated.

Thanks,
Shashishekar B S

zunkz0r said...

Hi I've read through this article and found it to be quite useful however when it came down to writing my own code I keep getting jQuery issues. I'll provide link to stackoverflow, nobody has managed to spot my issue yet and I'm just as oblivious having stared at it for hours.. I did enjoy the blog post though very informative :)

(stack overflow jquery issue link: http://stackoverflow.com/questions/31937213/jquery-reference-error-sharepoint2013 )

vikramsamal said...

Hello All,

I am facing weird issue in this. When i am trying to access my personal employee id I am able to do so. But when i am trying to get other suers I am not able to do so.
Vikram

Ram Bodake said...

I have to get all the users count and get only start with "A" users.
So do we can fire any kind of query on User Profile Manager Without search?
Is it possible with SP2013 custom code and how?

Vardhaman Deshpande said...

Hi Ram,

I don't think the User Profile Service allows you to search for users. You will have to use the Search API for that.

Ram Bodake said...

Can you please give some reference for the same?
I am using https://msdn.microsoft.com/en-us/library/office/dn423226.aspx#code-snippet-3
But still have some issues.