Monday, November 9, 2015

Using AngularJS and REST to display list data in SharePoint hosted app

AngularJS is now best way to work on the MVC pattern at client side. In this post, I will walk you through how we can display the data from a SharePoint list in a SharePoint hosted app using AngularJS and SharePoint REST. My assumption is that you have basic understanding of AngularJS and SharePoint REST.
  • Create a SharePoint hosted app.
  • Create a Contacts List in app web.
  • Add a reference of AngularJS to default.aspx
In the default.aspx, add the below code.

  <div ng-app="myApp">  
     <div ng-controller="customersCtrl">  
       <table>  
         <tr>  
           <th>Last Name</th>  
           <th>First Name</th>  
         </tr>  
         <tr ng-repeat="x in Contacts">  
           <td>{{ x.Title }}</td>  
           <td>{{ x.FirstName }}</td>  
         </tr>  
       </table>  
     </div>  
   </div>  

In the above code, ng-app is used to specify that its an AngularJS app and ng-controller is the controller.

Add the below code in the App.JS file.


 'use strict';  
 var myapp = angular.module('myApp', []);  
 myapp.controller('customersCtrl', function ($scope, $http) {  
   var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('Contacts')/items?$select=Title,FirstName"; 
   $http({  
     method: "GET",  
     url: restUrl,  
     headers: { "Accept": "application/json;odata=verbose" }  
   }).success(function (data) {  
     $scope.Contacts = data.d.results;  
   }).error(function (sender,args) {  
     alert("Error:" + args.message);  
   });  
 });  
 function getQueryStringParameter(paramToRetrieve) {  
   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] == paramToRetrieve)  
       return singleParam[1];  
   }  
 }  

Change the restUrl to below if you wanted to query Host Web.

   var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));

   var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.AppContextSite(@target)" + "/web/lists/getbytitle('Contacts')/items?$select=Title,FirstName,Company" +  "&@target='" + hostUrl + "'";


In the above code, we are getting the results from the contacts lists and assigning it to Contacts collection of $scope.
Add few items in the contacts lists by navigating to Lists/Contacts url






















Run the code, the results of the code is something like below


Wednesday, November 4, 2015

Get app web and host web title using jQuery promises in SharePoint hosted app

In my previous post, I talked about getting the app web title using jQuery promises. In this post we will talk about how to get the app web as well as host web title using jQuery promises in SharePoint hosted app.

Below is the simple code to get the title of both the web.

 var def = $.Deferred();  
 $(document).ready(function () {  
   var promise = GetHostWebTitle();  
   promise.then(  
     function (hostTitle, appTitle) { $('#message').text("Host web title : " + hostTitle+ ". App web Title : "+ appTitle) },  
     function (result) { $('#message').text("Error :" + result) }  
     );  
 });  
 var appContext;  
 var hostContext;  
 var hostWeb;  
 var appWeb;  
 function GetHostWebTitle() {  
   //Get the host web url from query string  
   var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));  
   //Get context fro host web and app web  
   appContext = SP.ClientContext.get_current();  
   hostContext = new SP.AppContextSite(appContext, hostUrl);  
   //Get the abb web and host web  
   appWeb = appContext.get_web();  
   hostWeb = hostContext.get_web();  
   appContext.load(appWeb, "Title");  
   appContext.load(hostWeb, "Title");  
   appContext.executeQueryAsync(onHostWebSuccess, onHostWebFailed);  
   return def.promise();  
 }  
 function onHostWebSuccess(sender, args) {  
   var hostWebTitle = hostWeb.get_title();  
   var appWebTitle = appWeb.get_title();  
   def.resolve(hostWebTitle, appWebTitle);  
 }  
 function onHostWebFailed(sender, args) {  
   def.reject(args.get_message());  
 }  
 function getQueryStringParameter(paramToRetrieve) {  
   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] == paramToRetrieve)  
       return singleParam[1];  
   }  
 }  

Once you run the above code, you will get the error as Access Denied on host web.












To resolve this issue, make sure you grant read access to the host web using AppManifest file.












Once you granted the access, the output result will show you the host web and app web title.














In the above example we are getting the host web context by using the below line.

 hostContext = new SP.AppContextSite(appContext, hostUrl); 

Also, you can pass multiple parameters when your deferred is resolved. In the above example, I am passing two parameters to the call back function.

 def.resolve(hostWebTitle, appWebTitle);  

Using jQuery Deferred and Promises in SharePoint Hosted App

jQuery promises are awesome when you wanted to work with aysnc calls in SharePoint hosted app.

Below is the simple example to get the App web title in SharePoint 2013 using jQuery Promises.

 var def = $.Deferred();  
 $(document).ready(function () {  
   var promise = GetAppWeb();  
   promise.then(  
     function (result) { $('#message').text("The app web title is " + result) },  
     function (result) { $('#message').text("Error :" + result) }  
     );  
 });  
 var appContext;  
 var appWeb;  
 function GetAppWeb()  
 {  
   appContext = SP.ClientContext.get_current();  
   appWeb = appContext.get_web();  
   appContext.load(appWeb);  
   appContext.executeQueryAsync(onAppWebSuccess, onAppWebFailed);  
   return def.promise();  
 }  
 function onAppWebSuccess(sender, args)  
 {  
   var title = appWeb.get_title();  
   def.resolve(title);  
 }  
 function onAppWebFailed(sender,args)  
 {  
   def.reject(args.get_message());  
 }  

You can also use .done and .fail instead of .then function. The output of the above solution is as below