11/27/2014

Using SharePoint Property Bags in javascript code


SharePoint Property Bag allows to store configurations settings at different levels of the SharePoint hierarchy outside of the application itself. Property bag is basically a hash table of key-value pair options.
I'll show how to use Property Bag of a SPWeb object.
First of all you have to be sure that sp.js script is loaded. Usually SP.SOD.executeOrDelayUntilScriptLoaded is used to execute custom code after script is loaded. But sometimes (I don't really know why) it doesn't work. That's why you can insert a call of SP.SOD.executeFunc fucntion before executeOrDelayUntilScriptLoaded. And that will work in any case:
// we need both calls because in some situations executeOrDelayUntilScriptLoaded doesn't work
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () { });
SP.SOD.executeOrDelayUntilScriptLoaded(function () {
    // code goes here
}, 'sp.js');
After the script is loaded you can access currentContext object and get web to work with:
var spContext = SP.ClientContext.get_current(),
spWeb = spContext.get_web();
Actually you have no web object before you call load and executeQueryAsync functions of currentContext instance (you can read msdn post for clarification).
The first parameter of load function is an object that contains the properties to retrieve from the server. Other parameters are optional and contain names of additional properties you want to retrieve.
In our case you need to get AllProperties property from the server:
spContext.load(spWeb, 'AllProperties');
Actually, AllProperties client object is a wrapping-object. That's why you need to call internal function to get key-value pairs of the Property Bag:
 var allProps = spWeb.get_allProperties(),
// actually allProps.get_fieldValues() contains key-value pairs of the Property Bag
allPropsValues = allProps.get_fieldValues(),
// value of the specific key
value = allPropsValues[key];
To set some property to the Property Bag you should write something like that:
allProps.set_item(key, value);
spWeb.update();
spContext.executeQueryAsync(function () {
    // some code
}, function () {
    //some logging code
});
value should be a string. Use JSON.stringify() to convert json object to string and store it to the Property Bag (you can than use JSON.parse() to restore the object).
Full test code looks like that:
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () { });
SP.SOD.executeOrDelayUntilScriptLoaded(function () {
    var spContext = SP.ClientContext.get_current(),
    spWeb = spContext.get_web();
    spContext.load(spWeb, 'AllProperties');
    spContext.executeQueryAsync(function () {
        
        var allProps = spWeb.get_allProperties(),
        key = 'testKey',
        // actually allProps.get_fieldValues() contains key-value pairs of the Property Bag
        allPropsValues = allProps.get_fieldValues(),
        // value of the specific key
        value = allPropsValues[key];

        allProps.set_item(key, value);
        spWeb.update();
        spContext.executeQueryAsync(function () {
            // some code
        }, function () {
            //some logging code
        });
    });
}, 'sp.js');
I'll be glad to have comments and feedback.
Have fun! 

2 comments:

  1. HI. Great article. Just one issue regarding spWeb.update()... when I test this code on the SharePoint Online Site I get an error "Access denied", but this works perfect on my on-premises... I can't understand the reason?

    ReplyDelete
    Replies
    1. Hello.
      You may not have permissions to modify the web.
      What is the level of permissions of your user?

      Delete