Tuesday, 1 September 2015

Index web property bag using JavaScript object model-AngularJS in SharePoint online

SharePoint 2013 added a new capability to index the property bags. Indexing property bag through the server side object model code is pretty easy. The WEB object has a property called "IndexedPropertyKey" which is a collection of all the web properties that should be indexed. Here is a reference article . However, doing this through client object model is tricky because we do not have access to IndexedPropertyKey through CSOM. Vesa Juvonen has made our life easy by documenting a work-around to do this through CSOM.

Basically the way this works is - all the properties that need to be indexed are encoded and stored in a "vti_indexedpropertykeys" property. In a scenario where multiple properties need to be indexed, the encoded values are separated by a PIPE "|" character. In this post we are going to index the web properties using JavaScript object model on a SharePoint online site. We will develop a SharePoint hosted app to add and index a property. Here is how our application will look like.
















Lets go ahead and add a couple of new properties to be indexed.




















The checkbox facilitates the user to choose whether the new property should be indexed or not. As we have chosen to index the properties , the vti_indexedpropertykeys is created in the web properties with the encoded values of property keys separated by PIPE character










Once the incremental crawl completes, the web properties that we just added are indexed.





















Lets go through the code


The AngularJS code has a controller "SPWebPropertiesController" and an AngularJS service "WebPropertiesService" which contains function to fetch and add new web properties. The function $scope.GetWebProperties uses AngularJS defer and on success, it populates the keys and values of the properties. It also checks whether the key "vti_indexedpropertykeys" exists and sets the flag $scope.vtiIndexedPropertyKeysExists accordingly.

All the AngularJS and Javascript code below is a part of single JavaScript file. It is separated here in this post and GIT for the ease of understanding.

  


FetchWebProperties function:

This function gets all the properties from the property bag and returns it to the controller where the key and values are populated in $scope.WebProperties=[];

AddNewProperty function: 

- This function adds a new property to the property bag using the set_item(Property_Key, Property_Value) function. If you want to modify the value of a property, use "webProps.set_item(Existing_Property_Key, New_Value)".
- If we have chosen to index the property using the checkbox, we must get the encoded value of the property key. This is done using the EncodePropertyKey function.
- Checks whether the key "vti_indexedpropertykeys" exists, using the flag that we have set in GetWebProperties function of the controller. If it exists, it adds the encoded property key.
- If the "vti_indexedpropertykeys" is not present, it creates this new key and then adds the encoded property key that has to be indexed.

EncodePropertyKey function : 

This function converts the property key to an encoded string. Initially I observed the bytes array in C# console application and Javascript conversion and noticed that the '0's from JS conversion were missing. So I added those (line 5 in the below function)


WebPropertiesService code :

4 comments:

  1. I'll voice my opinion here that even though you can stuff data in the property bag and get it indexed, I'm not a big fan of this and like to promote other approaches instead. The TCO of doing this to me is often too high.

    ReplyDelete
    Replies
    1. Thanks for your comment Mikael. I was thinking of a scenario where you have to build a site directory and each site has properties like "Confidentiality level", "Department" etc and these properties have to be displayed. Would be easier to simply fire a search query and build the directory. But i agree there may not be many scenarios where this is helpful. Would love to hear you elaborate on your point of high TCO and also whether your point is specific to SP Online or on premise too ?

      Delete
    2. Hi, take a look at my content type approach: http://techmikael.blogspot.com/2015/04/why-content-types-are-still-awesome-and.html

      Delete
    3. Ah.This is a great post. Thanks for sharing :)

      Delete