Tuesday 30 August 2016

Dealing with async REST API calls in the SharePoint Framework with Promises and HttpClient/jQuery AJAX

Promises calling code

To be able to do anything useful, one of the things to get to grips with in the SharePoint Framework is how to call web APIs such as SharePoint’s REST API, the Office Graph or any other REST APIs which you would hit with a web request. Clearly these need to be async operations - if you attempt to implement in some other way, you’ll run into timing issues because, for example, your web part tries to render before the HTTP/AJAX call has actually returned, and so no data appears. You might have worked with Promises before (perhaps jQuery Promises), but in SPFX the Promises Framework used is ES6 Promises – so it’s a good idea for your methods to return this type of promise rather than a jQueryPromise. We also have to deal with this in TypeScript, so in short there are a few changes to what you might have done before.

You most likely used jQuery’s AJAX methods to make REST calls before – either $.ajax, $.get or $.post. These methods still work fine in the SharePoint Framework, but note that SPFX brings some built-in objects to make web requests instead – namely the HttpClient and BasicHttpClient objects. The HttpClient object will automatically add auth tokens to outgoing requests which require them, and so calling Office 365 APIs, the Graph, or indeed anything else secured with the same Azure AD becomes easier. I’ll talk about the HttpClient/BasicHttpClient objects a little more, but in this post I want to focus on the Promises and coding aspects, so let’s start there.

By the way, my recommendation is that you use the HttpClient object over jQuery AJAX *because* it simplifies POST requests which change data. Even though you might be using GET operations sometimes (like I am in this post against SharePoint’s search API), there are benefits to staying consistent. However, I’ll show both approaches (HttpClient and jQuery) in this post so you can compare.

Implementing the code

The promise represents data passed back from the async HTTP call, and provides then() and catch() methods for your calling code – this allows you to implement a chain of async operations and deal with success/failure of each one. The best thing to do is usually to create an interface or other kind of contract in TypeScript to represent the data being passed. So in the case of calling search, we would return an array of result items – but for illustration, let’s say we also want to return some other properties too, like a message. Our interface may then look something like:

** N.B. There is a code sample here (and in several other places in this article) but it will not show in RSS Readers - click here for full article **

So that's an interface (and SearchResult class) that we've defined. But also note that when working with APIs that return well-defined JSON, you might choose to define additional interfaces, so that you're working with strongly typed objects in TypeScript. Ideally there would be a typings file that some other kind person has greated for these classes/interfaces, but many SharePoint things you'll work with (e.g. SharePoint search results) don't have a good typings file currently. So, you might define your own to represent an object hierarchy, like this:

(Shout out to Elio Struyf here, as I noticed he did something similar in his search web part sample - this will be a common approach I think.)

Using the HttpClient object to make web requests

Perhaps the first thing to mention here is the difference between the HttpClient and BasicHttpClient objects in SPFX. It can be summarized like this:

Object

Use

Why

HttpClient To hit SharePoint REST services Automatically adds the X-RequestDigest header and value (which you’d previously need to obtain via a separate request to /_api/contextinfo) to POST (i.e. write) operations, and sets some other appropriate headers too.
BasicHttpClient To hit other REST services Useful for any non-SharePoint API, without having to bring in an entire framework such as jQuery just for web requests.

The sample below uses the HttpClient with Promises. Some things to note about this code:

  • Since the HttpClient object is accessed through the web part’s Context property (IWebPartContext), we need access to that in this “middle-tier” code.
  • As usual, we resolve or reject the promise with the object that represents our data - in this case an instance based on our custom interface.
  • The first function is a simple function that is largely re-usable. The Promise type it returns is our custom object representing JSON from the SharePoint search API. You could work directly with the JSON by using “any” in TypeScript rather than providing a type for this data – but then your consuming code would not have auto-complete.
  • The second function does the surrounding work of obtaining the correct URL to use, and translating the raw search return data into the object we really want to pass back to the calling code – a Promise of type ISearchResult (the one with the Message and SearchResults array).

So, that’s the async method and the calling code using HttpClient. Let’s now look at jQuery AJAX.

Using jQuery AJAX to make web requests

I can’t really think of any advantages to using jQuery AJAX instead of HttpClient, apart from the fact your development team might be more used to it (and you don’t always need what HttpClient gives you). But maybe that’s a good enough reason for some – the objects aren’t too different to use and maybe it’s not something we should get religious about.

Some things to note about this code:

  • The overall structure is very similar – we return a promise of type ISearchResult, and we have to resolve/reject the promise depending on success/failure of our core request.
  • Again, we can work with strongly-typed objects by providing a type to the object passed to the done() callback (named “data” in my code). This gives us auto-complete to the calling code.
  • There may be further TypeScript improvements to make e.g. typing the reject/resolve objects. I’m assuming this is possible, and might be worthwhile if you find yourself using jQuery AJAX in TypeScript a lot.

Summary

So that’s hopefully some use as you are starting to do more in the SharePoint Framework. There are some other TypeScript things in there to think about, such as use of the “fat arrow” syntax (=>) for anonymous functions, but TSLint and the default settings will be only to happy to point things like this out for you if you don’t use them (in the form of compile errors :)). A couple of other things to think about here include the info my colleague and buddy Vardhaman supplies in Making a POST request to SharePoint from an SPFx webpart and also a TypeScript thing:

  • If you’re struggling with providing types for JSON returned from SharePoint (or other) APIs, then you can choose to declare the type as “any” in your TypeScript code instead. It’s nicer to avoid this where possible, but hey, Rome wasn’t built in a day right? Smile

Tuesday 9 August 2016

Introduction to the SharePoint Framework – presentation slides available

I presented recently at the SharePoint Saturday London 2016 event, on the topic of developing with the new SharePoint Framework. As more and more SharePoint developers are coming to realize, it’s a time of big changes and although the SharePoint Framework has not yet hit general availability (at the time of this article), it’s very very close and so it’s good to start soaking up the information. I held back publishing this slide deck, as I knew Microsoft were making some changes to the Framework since I first saw it and were going to release some updated bits to us folks with early access. I wanted this ‘early preview’ information to remain as accurate as possible for when *you* get the Framework, and I’ve now verified everything in the deck is still accurate.

The deck is available for download on SlideShare at http://www.slideshare.net/chrisobrien/chris-obrien-introduction-to-the-sharepoint-framework-for-developers, but you can also flick through the slides below. Unfortunately the demos weren’t recorded at the event – so I’ve added a couple of slides to describe them in case that helps.

 

Looking forward

Hopefully the SharePoint Framework will start rolling out to Office 365 tenants in First Release mode soon. It’s a radically different development experience, and the payback is that you can develop performant web parts that work well in responsive design and can be used in “modern pages”. Rememeber that it's not possible to use what we're now calling "classic" web parts in modern pages, and given that both team sites and publishing sites in Office 365 will soon be able to use modern pages, that alone makes the new model worthy of attention. Additionally, it will come to on-premises SharePoint 2016 in a Feature Pack in 2017, so even if you're on-prem only it's perhaps advisable to start looking at this.

Onwards and upwards!

Monday 1 August 2016

Sandbox code no longer available in Office 365 – with immediate effect

Most technical people working with Office 365 have known that sandbox code has been deprecated for some time. This doesn’t mean any sandbox solution is deprecated however – instead, the deprecation specifically refers to *code* in sandbox solutions, and by that we mean code which uses the server-side API. No Code Sandbox Solutions (NCSS) continue to be supported. This advance warning about sandbox code was given back in January 2014 in https://blogs.msdn.microsoft.com/sharepointdev/2014/01/14/deprecation-of-custom-code-in-sandboxed-solutions/. Since then however, no timeline for the actual removal of the feature was announced – and in fact there was no news whatsoever. I even heard from some Microsoft folks that the urgency of removing sandbox code from SharePoint Online had gone away, since the original operational concerns weren’t materializing and in fact the engineering team were able to run and scale the feature just fine in Office 365.

So a big surprise last week was the sudden removal of the feature in many tenants. The “Activate” button against a solution is unavailable, and the following message is shown:

"Activation of solutions with sandboxed code has been disabled in this site collection. Contact your administrator to enable activation using the guidance published here."

SPO - sandbox code disabled

One very interesting aspect of this is that you will see this even if you’re not using sandbox code, but *are* deploying a code assembly – and this is the default in Visual Studio! So, lots of solutions which aren’t really using sandbox code at all will still need some attention – developers will need to repackage the WSP again, this time without including the auto-generated assembly. I discuss the specific change later in the “How do I remove auto-generated sandbox assemblies?” section.

Official Microsoft announcement

What effect will this have?

Well, it depends on which camp you fall in:

  1. You’re not actually using sandbox code, but have some auto-generated assemblies deployed.
  2. You genuinely are using sandbox code.

For number 1, your developers will need to make some relatively simple updates. See the “How do I remove auto-generated sandbox assemblies?” section.

For number 2, the short answer is you have a problem. Just how big depends on how sandbox code is being used, and how much of it you have. Ultimately you need to take action to re-engineer your solution now. You can’t wait until some code changes are scheduled, since bits of your solution may stop working very soon and you may have a service issue. Already, you will not be able to add new sandbox code or reactivate an existing sandbox WSP with code. Additionally, the Microsoft message states that you have 30 days before existing code will stop working. In technical terms, that means the following things will stop working:

  • Event receivers
  • Feature receivers
  • Workflows (coded)
  • InfoPath forms (if using code behind the forms)
  • Web parts (if coded using sandbox code)

Exactly what that means for your intranet or solution is down to how those building blocks have been used by the original developers.

Considering the impact

I’m really surprised at this – in the original deprecation announcement, Microsoft said:

We realize that our customers have made investments in coded sandboxed solutions and we will phase them out responsibly. Existing coded sandboxed solutions will continue to work in on-premises SharePoint farms for the foreseeable future.

Happily, none of my clients/projects are affected because we knew better than to build solutions using this approach. But I feel for organizations in a different situation. I was certainly expecting a significant “final warning” period and I’d heard it said that there would be at least a further 12 months from this point. But apparently not – and I know Microsoft have probably not breached any contract or element of the Office 365 Service Description here, but I struggle to see that this is “responsibly” taking a feature away from the service.

On a related note, I’ve being doing some work alongside Microsoft with a global enterprise (over 100,000 users) who have sandbox code in their Office 365 intranet – in light of this, it’s perhaps fortunate that they are not yet live. We didn’t create the initial solution, but flagged this in our review of their code, along with a few other things. I suggested the Microsoft folks reach out to their colleagues for clarification on the timeline for switching off sandbox code. Interestingly, the message that came back is that “everything should be fine for at least 12 months”, and so if it’s a surprise to these guys I think it’s fair to say it’s a surprise to many others too.

Communication troubles

Notably, there was some confusion as this was playing out initially. At first, this was being reported as a temporary service issue, and administrators may have seen a message to this effect in the Office 365 Message Center:

SPO - sandbox code service issue_

However, sandbox code really is being disabled – it just seems that for a while, other teams within Office 365 didn’t actually know either. You will now see one of two things in the Office 365 Admin Center:

Status

Message

You have a problem – sandbox code was detected

MC73347 - We’ve detected that you are using a code-based sandbox solution with your tenant account.

Please be advised that we’ve moved forward on our plans to remove code-based sandbox solutions as previously announced in 2014, which can be seen here: http://aka.ms/sandboxcode

Please note that declarative (no-code) sandbox solutions are still fully supported.

How does this affect me?

As part of the removal process, activation of new code-based sandboxed solutions, as well as updates of existing solutions are no longer available. In approximately 30 days, currently running, code-based sandbox solutions in the SharePoint Online environment will be disabled. If you have an extenuating circumstance, please contact us as our Product and Customer Support teams are ready to support you during this transition.

You’re OK – no sandbox code was detected

SP73009 - Custom Solutions and Workflows - False positive

Incident customer impact scope has been updated. Ongoing analysis of customer impact has determined that your service is not impacted by this incident

So that’s the final story it seems.

How do I remove auto-generated sandbox assemblies?

As mentioned earlier, developers may need to repackage WSP solutions without the auto-generated assembly. You can do this by setting the “Include Assembly in Package” project property to false:

clip_image005

This step may be necessary the next time some development or maintenance is carried out – effectively anything that would require activation of another version of a WSP.

Summary

We rely on Microsoft to make the right decisions in terms of running Office 365 (and on-premises SharePoint). I’ve no idea of the scale of sandbox code out there in real-life solutions, but I really hope the way this is being handled doesn’t affect too many organizations too badly. Are you affected by this? Or do you otherwise have views? I’d be interested in hearing how this is being received – feel free to leave a comment and let me know.