Wednesday, May 20, 2015

Get appWebUrl and hostUrl in SharePoint Online / Office 365

When you are developing in SharePoint Online / Office 365 you will have to fetch appWebUrl and hostUrl if you want to perform any operation on your lists and libraries. I could find two ways of getting these values.

1. Reading values of SPAppWebUrl and SPHostUrl from query string


When you run your project it opens up the page Default.aspx. The URL of this page looks something like this.


Notice the query string parameters of SPAppWebUrl and SPHostUrl. You can fetch these values via a helper function.

function getQueryStringParameter(param) {
    var params = document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == param) {
            return singleParam[1];
        }
    }
}

You can then use this helper function to fetch the appWebUrl & hostUrl and work with your lists and libraries.

var hostUrl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
var appWebUrl = decodeURIComponent(getQueryStringParameter('SPAppWebUrl'));

var context = new SP.ClientContext(appWebUrl);
var appContext = new SP.AppContextSite(context, hostUrl);

var web = appContext.get_web();
var lists = web.get_lists();

context.load(lists);
context.executeQueryAsync(onGetListsSuccess, onGetListsFail);

// Define functions of onGetListsSuccess and onGetListsFail

But the biggest drawback with this method is that it works for the first time when the page Default.apsx is loaded. If you navigate to another page the query string is no longer there.

2. Fetching appWebUrl and hostUrl using _spPageContextInfo object


This method relies on using the _spPageContextInfo object to get the appWebUrl and hostUrl. I won’t delve into the _spPageContextInfo object here as it would warrant another article of its own. As of now all you need to know is that you will find this object on every SharePoint page, so this method works regardless of which page the user is currently on.

You use the below code snippet to get the appWebUrl and hostUrl.

var appWebUrl = window.location.protocol + "//" + 
  window.location.host + 
  _spPageContextInfo.webServerRelativeUrl;
var hostUrl = _spPageContextInfo.siteAbsoluteUrl;

Below is the complete code snippet to use this method.

var context, appContext, web, user, lists, listItemCollection;

(function() {
 // This code runs when the DOM is ready and creates a context object which is 
 // needed to use the SharePoint object model
 $(document).ready(function() {
  var appWebUrl = window.location.protocol + "//" + window.location.host + _spPageContextInfo.webServerRelativeUrl;
  var hostUrl = _spPageContextInfo.siteAbsoluteUrl;

  context = new SP.ClientContext(appWebUrl);
  appContext = new SP.AppContextSite(context, hostUrl);

  user = appContext.get_web().get_currentUser();
  web = appContext.get_web();
  lists = web.get_lists();

  context.load(lists);
  context.executeQueryAsync(onGetListsSuccess, onGetListsFail);
      
  // Define functions of onGetListsSuccess and onGetListsFail
 });

})();

There are two things you should note here. First, you can only use the _spPageContextInfo object when the DOM is ready. So in effect you can use this object only inside $(document).ready. If you try to use the _spPageContextInfo object before DOM is ready then it will throw an error.

Second, while using _spPageContextInfo object in NAPA editor it always shows a red squiggly line and error of '_spPageContextInfo' is not defined.


This is because the object is added to the page dynamically, thus the editor is not aware of it. However when you run the project it works perfectly fine.

So to conclude, the second option is the best and probably the only option if you are developing for production.

No comments:

Post a Comment