SharePoint 2013 JSOM and Social API

The SharePoint team at Microsoft has done a great job preparing for the launch of SharePoint 2013. The number of developer samples, video, and blog post has been a tremendous help getting ready for the changes to the platform. While preparing for my session at the SharePoint Conference 2012 (#SPC12) I found the code samples to be very helpful for presenting the basics of how the access and use the social API. For example, the article How to: Read and write to the social feed by using the JavaScript object model in SharePoint 2013 has several tricks for working with the JavaScript Object Model (JSOM) in SharePoint 2013. With this as our starting point, I decided to try to incorporate the Personal Feed into the new People search results. Here is the result that I am building. All of the code is contained in the Hover Panel, you can download it here. As I write this post I realize there are a LOT of dependent technologies in play. For example, the people you seek must have My Sites in order to participate in 2013 Social, this is a new requirement based on the new storage model. Also, adding display templates to Search is a whole topic on it’s own, I’ll cover that briefly in this post and in detail in a follow-up post. Anyway, here is the finished product from this demo.

Search Page with Social added in

JOSM and Social Methods

Calling Social with JOSM is done just like it is with other JSOM functions with a few new Social objects thrown in for added functionality:

  1. Get a Client Context
  2. Create a SP.Social.SocialFeedManager and supply various options.
  3. Get the required feed from the FeedManager (we’ll target a user, but you can also get a Personal Feed or the public NewsFeed)
  4. Load the Context and then call executeQueryAsync to fetch the results asynchronously.
  5. Finally we process the results and perform data manipulations to create the presentation in the UI. As usual, this is the biggest section of the code.

The code samples that follow highlight the important sections of code. The samples are not complete. For the complete code sample download the code and review it.

Get the ClientContext

As it turns out, this was one of the most problematic sections. I had trouble getting the timing right in the search page to be certain that the ClientContext would load correctly. Here I demonstrate how I get the client context. Below, in Search Tricks, I demonstrate how to get the timing right and ensure that you are calling your function after all the JavaScript has loaded. This code snippet also demonstrates how I have been debugging my HoverPanel. Using IE and the Developer Tools, you can write to the Script debugger panel with the console.log method. This enables your code to run at full speed while debugging without getting in the way of the hover behavior.

// Initialize the current client context and the SocialFeedManager instance.
try
{
    console.log("Get Client Context...");
    clientContext = SP.ClientContext.get_current();
}
catch(err)
{
    console.log(err.message);
    return;
}

This is what the debugger looks like after a few successful runs:

JavaScript Debugging

Create the FeedManager with Options

Create the FeedManager by passing the ClientContext to the constructor of the SocialFeedManager. Then, optionally, set the necessary options for the results. In this case I only want 5 threads, but I could also change the sort order and other options.

feedManager = new SP.Social.SocialFeedManager(clientContext);
// Set parameters for the feed content that you want to retrieve.
var feedOptions = new SP.Social.SocialFeedOptions();
feedOptions.set_maxThreadCount(5); // default is 20

Choose the Feed to Get

You have a choice of the feeds for the FeedManager to return. In this sample I am interested in the Users feed (or timeline or whatever you call it today.) So I’ll use the getFeedFor method and pass a username. (I get the user name from the Search Result, more on this later.) If I wanted the logged in users Personal Feed I would use getFeed and pass SP.Social.SocialFeedType.personal, for News pass SP.Social.SocialFeedType.news and timeline takes SP.Social.SocialFeedType.timeline.

targetUserFeed = feedManager.getFeedFor(targetUser, feedOptions);

Load the ClientContext and Execute

The last step is to load the ClientContext and then execute the query. The query function takes a success and failure callback. If successful we can write the results to the UI, if fail you can write the error (or handle it some other way) or just pass null and ignore the error.

clientContext.load(feedManager);
clientContext.executeQueryAsync(CallIterateFunctionForFeeds, RequestFailed);

There are many new features in Search for SharePoint 2013. I plan to write a couple articles about how to create cool new search visualizations using Display Templates, but for now I’ll show you a quick way to add your code to the People Search Result template.

  1. Open Design Manager for your Search Site and navigate to \site_catalogs\DIsplay Templates\Search in explorer.
  2. Make a copy of Item_Person.html and Item_Person_HoverPanel.html. Rename these copies to Item_Person_Social.html and Item_Person_Social_HoverPanel.html respectively.
  3. Open Item_Person.html in any editor and change the Title tag to “People Social Item”.
  4. Next, locate the following line in the head:
    var hoverUrl = "~sitecollection/\_catalogs/masterpage/Display Templates/Search/Item\_Person_HoverPanel.js";
  5. Change it to point to your new Social Hover panel:
    var hoverUrl = "~sitecollection/\_catalogs/masterpage/Display Templates/Search/Item\_Person\_Social\_HoverPanel.js";
  6. Save and Close the file.
  7. Open Item_Person_Social_HoverPanel.html and insert your code. Depending on what you are trying to accomplish you may need to play around with where to put your code. In my case I added the new variables and methods on line 54, just before the line:
    if ($isEmptyString(uname)) { uname = ctx.CurrentItem.YomiDisplayName }
  8. You need a place to display your results. I did this in my Hover Panel display template by using the same look and feel from the rest of the page. Notice the special tag socialId. I’ll elaborate on this in the Tricks session.
    <li>
    <div class="ms-srch-hover-subTitle"><h3 class="ms-soften">SPC Social Feed</h3></div>
    <table width="100%" id="_#= socialId =#_"></table><br/>
    <span id="spanMessage_#= socialId =#_" style="color: #FF0000;"></span>
    </li>
  9. Finally, you need to call all this code from some event, like after the whole page has loaded. The best method to use in a Search Results page is the AddPostRenderCallback method. This ensures that the whole page has loaded before you call your code. The full description is in the next section.
    //SPC: Post Render Callback
    AddPostRenderCallback(ctx, function(){
        console.log("Post render callback: " + ctx.CurrentItem.AccountName + "(" + socialId + ")");
        SP.SOD.executeFunc('sp.js', 'SP.ClientContext',function()
        {
            console.log("Calling GetFeeds in execFunc...");
            GetFeeds(ctx.CurrentItem.AccountName, true );
        });
    });
  10. Save and Close the page. To make your page live in the Search results, see the How to Render Social Results trick below.

Search Page Tricks

As I worked through this demo I found that many of the challenges were caused by the new Search page loading procedure. You have to be certain that your code runs after the page is finished loading. I also needed to target specific di tags on the result page. I used another trick to ensure that I had unique IDs on the page. I solved these two challenges as follows.

Script Load Timing

If your scripts fail to load correctly you will get the dreaded “Unable to get Client Context” or you will simply have a null ClientContext to deal with. I found that, for a while, my script worked fine, then, later for no apparent reason, they did not. Some process changed the timing and now my script was failing. In order to force SharePoint to ensure that my script loaded correctly I found that I had to call SP.SOD.executeFunc. You may be familiar with executeOrDelayUntilScriptLoaded, I was, but I found that it would randomly fail and not throw an error. I found executeFunc to be the most reliable function for this purpose. So, in the end, I wrapped my GetFeeds function with the executeFunc to ensure that I would always get a ClientContext.

Unique Tag IDs

If you look at the Table that I created in the display template above, I used a substitution tag for the page of socialId. The “_#=” markup is used by the Display Template to perform replacements when the page is running. (I really need to write a post about this…). The cool thing is it will replace any page variable. In my case I needed to uniquely identify the tables for the social data I was returning. All I had to do was create a variable and then reference it in my code. I create the variable like this:

var socialId = encodedId + "_hoverSocial";

Which appends “_hoverSocial” to the unique encoded ID of the result that was hovered over. Now I have a variable for my JQuery to reference the right instance of the table for my Social Results.

Get the Target User Name

In my scenario I wanted the User Name of the person I am looking at in the Search Results page. Since this is a People Search Result I have access to the Managed Property “AccountName” that is associated with the context of the CurrentItem. (OK, I seriously need to write up another post to make this more clear.) Any way, if you look at the method where I am calling GetFeeds, I pass in the {%%} as ctx.CurrentItem.AccountName.

How to Render the Social Results

One of the trickier parts of making this work has nothing to do with development. I simply needed to change the behavior of People Search so that SharePoint would load my result types rather than the defaults. Here are the steps to make that happen. Note, you have to have already added the Item_Person_Social and Item_Person_Social_HoverPanel HTML files before you attempt this action. They need to be present to get the wire-up to work.

  1. In the Search Site | Site Settings choose Result Types from the Search Section.
  2. Choose New Result Type.
  3. Provide the following information:
    • Name: Social Person
    • Conditions: Local People Results
    • Action: People Social Item (This is your display template. You remembered to publish it, right?) The display template URL should match your file name.
  4. Click Save and you should see your new Result Type at the top of the list. Since it is at the top it is going to over rule the one for the default People results.
  5. Test your work by executing a People query in the search center and you should see your new template and hover panel. (If not, debug it as you normally would debug JavaScript.) Remember, the person you found has to have Social Data for this to work, so create a My Site for them and add a couple posts.

Final Results

The final results are simple but they show how powerful this new version of SharePoint is for developers. We are able to implement a cool addition to search using the out of the box APIs and without deploying code to the server (beyond the JavaScript that we just waded through).

|| JavaScript || JSOM || Search || SharePoint 2013 || Social Features

comments powered by Disqus

Let's Get In Touch!


Ready to start your next project with us? That’s great! Give us a call or send us an email and we will get back to you as soon as possible!

+1.512.539.0322