codescrenshot

SharePoint REST API to Host Web with AngularJS Services

I’ve been working more this weekend on my SharePoint 2013 App I’m submitting to the store and using as a basis for my SharePoint Conference 2014 session in March. I’m really starting to get the hang of AngularJS and spent Saturday on integrating Bootstrap for UI stuff and then today experimenting with REST API after being very comfortable with CSOM API because its closer to what I’m used to in C# managed code space. I’ve barely worked with  JSON in the past, typically iterating through collections like SPListItemCollection etc.

I was using a CSOM call to SP.AppContextSite to call the Host Web of my App Web to fetch List Items from a Task List. I have written a series of posts on this already. I am trying to switch totally to REST from CSOM as it is more well known by Web Developers in general which is a major ploy in my SPC14 session. I decided to approach this in steps:

  1. Write a sample app that just called the REST API and returned List Items for the Task List in my App Web using $https in a AngularJS Service
  2. Change this to call a Task List in the Host Web

Calling the App Web

There are plenty of samples to call the REST API in an App Web on MSDN already and with AngularJS you can actually make the call even cleaner using angular.forEach and Services.

Controller

Service

Here is the Service code note how I’m using $http to call the REST API and returning it up to the caller in code snippet above:

REST URL Filters $expand

The biggest bit that burnt me time was the REST URL to build [line 9]. For Host Web you have to add the “@target” into the URL. The nice thing is that if you put a breakpoint in your code you can actually grab the URL it builds in Visual Studio, copy and paste it into a browser and see the response to test its working before you start troubleshooting your code. A big thanks to Andrew Connell for his post on REST API URLs with joining the List Data to get the User Names, and a big thanks to Marc Anderson for adding the sample in the comments to grab the Authors Display Name. This saves multiple calls to SharePoint and is easy to test directly in the browser address bar.

Calling the Host Web

There were some samples on REST API for Host Web on MSDN/TechNet also but just to point out the most important thing about the URL you build is the “@target” bit…otherwise it won’t work!

Here is the code for the Angular Service:

 SP.RequestExecutor and SP.AppContextSite

To call the Host Web, not only do you need to modify your App Manifest to ask for Read to the ‘Web’ object you also can’t just call the REST API URL in the straight forward way. You have to use the SP.RequestExecutor object which handles the cross-domain complexity of SharePoint Host Web URL being different from your App Web URL.

In all the examples you’ll see a lot of them using the $getScript() function, which is actually unnecessary if you simply add the .js file to your .aspx page. This saves another bunch of nested functions:

I’m also not a big fan of all the daisy chaining of calling functions in functions with success [line 16] and error [line 19] so I call the functions inline.

Promises

I use of $.Deferred() [line 3] approach it allows me to call this from my AngularJS controller handle the async of the SP.RequestExecutor to be handled correctly.  I was trying to get the AngularJS Service $q.defer() to work but couldn’t get the .then to fire properly using the SP.RequestExecutor(). I had some trouble with the syntax of the deferred and was returning deferred.promise and this was causing problems so just returned deferred [line 23], this was because I was getting mixed samples with $.Deferred() and $q.defer().

Controller

The code for my controller for the loading of my tasks looks like this:

Take note of [line 18] of the above sample where I force the $scope.$apply() to update the bindings in my controller based on the $scope.todos being populated. Andrew Connell also pointed me to a good JSON formatter to visualize the return object a little easier to work out the instructions to navigate to the collection correctly…in this case it was “jsonObject.d.results”.

Here is the returned JSON formatted if you’ve not played with REST API yet and interested. It makes it a lot easier to see what the Names are of the fields when mapping into your $scope objects like above.

 Wrapping Up

A big thanks goes out to Andrew Connell who I was chatting to on Skype whilst he watched the Seahawks beat Tom Brady’s crew to get to the Super Bowl in two weeks in NYC! I had been using search engines to discover how to hook all this stuff together, but needed someone to be my “cardboard cutout” to ask question and then realize that I could answer them once I’d posed them. He pointed me to a few good posts on JavaScript Promises as I had my syntax wrong and also pointed out a problem with my parsing of what was returned from the RequestExecutor method. SO thanks!

I’ll try and resolve the issue with $q.defer() in the future! My next steps is refactoring the AngularJS services so I can swap it out for a mock service separating SharePoint from my business logic and presentation layer. I’ll just throw up the JSON I get above and add some extra data. This then allows me to get a Web Developer to work on these two layers without needing SharePoint at all which is massively easier than it was in the tightly mashed together world of Solutions development!

9 thoughts on “SharePoint REST API to Host Web with AngularJS Services”

    1. You’re welcome mate, I’m learning a lot being on the client side and excited to share the journey at SPC14 as I know there are a lot of people in the same boat! I know lots have been in the JavaScript/REST space for a while, so i’m playing catch up there…but AngularJS is a new area and exciting to take the principals into the SharePoint App Model!

  1. Great lesson!!! When using Angular with SharePoint 2013 Apps, is routing still possible? Microsoft puts so much into their URL variables I am concerned and HOPE that you were accurate when you said that once you use the div on the Default.aspx as ng-app, it’s just like writing a stand-alone app.

Leave a Reply