Friday 2 December 2016

We’re starting to write production code on the SharePoint Framework now. Should you?

I’ve been writing and speaking on the SharePoint Framework (SPFx) for a while now, but in many ways it’s all been a bit theoretical so far. After all, SPFx is still in preview at the time of writing (early December 2016) with General Availability expected soon. However, I’ve started to realize that some web parts we are specifying and building for clients now actually need to be done in the Framework. The principal reason for this is that we need them to work in modern pages – and web parts developed using previous approaches way will not work there. On this, I’ve been using this slide recently to explain what works where:

image

Essentially, a modern (SPFx) web part can work in both modern and classic pages. But a classic web part can only work in classic pages.

Let’s be clear on what we mean by that:

Modern pages use modern web parts
Modern pages cannot use any “classic” web part, including the Content Editor web part, Script Editor web part, Content Search web part, Content Query web part, or any custom web part based on one of these. This means that all the out-of-the-box web parts we’re used to in SharePoint cannot be used in these pages. Microsoft provide a new family of OOTB web parts which meet many common needs, and also address newer scenarios too (e.g. a Power BI web part to embed a Power BI report).
 
It also means that any “cloud-friendly” custom web part which uses the common “Script Editor/Content Editor web part + JavaScript” embed approach will not work in it’s current form – however, I’d expect Microsoft to at least provide an equivalent way to easily add JS to a page e.g. a new Script Editor-like web part). Maybe they’ll even go further and provide a zero-friction way of migrating such web parts?

So, this is kind of a big deal. Of course, the other aspect to consider is how much of a problem all this is..

How prevalent are modern pages? Which pages are modern?

As I mentioned in my previous article Modern SharePoint pages and team news pages - how to query/search for them, the new team news feature uses modern pages and it’s now the default when a new page is created. A more complete list of modern pages might be:

  • Any new page created with the “Add page” menu item (from now)
  • Any team news page
  • Modern list/library pages (but currently not extensible – web parts cannot be added)
  • The Office 365 profile page (but currently not extensible – web parts cannot be added)
  • Delve blog pages, though these are a slightly different (earlier) flavour

You can identify a modern page quite easily – it has the site logo displayed, slim toolbar and then the tall banner containing the page title:

SNAGHTML26d35183

Of course, Microsoft might update this look and feel at some point, but that’s how it is for now.

The new web part picker

At the heart of the matter is the new web part picker. When you edit a modern page and go to add a web part, you’ll see this and it’s a much simpler experience than before – no wrestling with the ribbon, no navigating through lots of categories of web parts you never use:

image

image

Of course, where I’m getting to with this is that only Microsoft’s new web parts and our web parts developed in the SharePoint Framework will show up here. It’s worth becoming familiar with these web parts because they are the new building blocks – but note that more will be added soon, such as the Power BI web part (which might just be awesome, if authentication works in a simple or automatic way). Consider also the new Highlighted Content web part – this is a modern version of something approaching the Content Search web part, but it doesn’t quite have the same power. It *is* easier to use though (much), and based on my experience with end-users I think it really is the direction Microsoft had to head in.

Another thing to think about is that with a new web part picker, the previous requirements of needing web parts to be added to the web part gallery of the current site collection doesn’t necessarily still need to be the case. In the SharePoint Framework, the requirement is currently that the app package must be installed to the App Catalog and for the app to be installed to the site – nothing goes in the web part gallery. But SPFx is still in preview, and Microsoft have some options here - it will be interesting to see where things end up once it hits General Availability.

Summary

So, a new page and web part model. We’re seeing new pages mainly be applied to SharePoint team sites so far, but I think it’s clear that publishing sites will receive similar updates in the future. At that point, it’s fair to expect that, again, only Microsoft’s new web parts and SPFx web parts will work in those pages. The main message here is that modern pages are starting to become prevalent (and the default), and users are using them – so if you’re customizing SharePoint or adding new functionality based on web parts, you might run into problems soon if your web part will not work here. This is driving us to create new web parts using SPFx, and maybe it should for you too. Just make sure you have a fall-back plan in case timelines don’t align – for example, you need to make your web part available in full production mode (and be fully supported) before Microsoft get to SPFx General Availability in non-First Release tenants.

Thursday 24 November 2016

Modern SharePoint pages and team news pages - how to query/search for them

Modern pages are now in SharePoint team sites in Office 365, and this includes the new “team news” facility. This is a simple way of creating news articles within a team site - it’s no replacement for an organization-wide intranet news facility, but it is useful for teams to convey news or other information within their group. And whilst it’s called “news”, of course the pages themselves could be anything – reminders for the team, current priorities/focus areas, policies and procedures, and anything else. One key element is that users can easily submit these articles from their mobile device – specifically the SharePoint mobile app. But it’s just a page with text, images, and any other web parts that the author adds (though that bit needs the PC experience).

I spent a little time looking at how all this works, and how developers and power users can query and search for such pages. Just to set the context since this is all shiny and new at the time of writing, this is what a display of team news looks like:

(By the way, excuse the horrible branding in this tenant - I use it to clearly tell me which of my test tenants this is!)

News page

In the context of a group site (i.e. a modern site attached to an Office 365 Group), things look a little different in terms of the page header/banner, but largely the same:

News page - Group

..and then to zoom in a little on the “News headlines” control:

News headlines

..or as an alternative, the “News list” control:

News list

Both of those are new web parts that you can add to a modern page – and since new-style web parts developed with the SharePoint Framework can be used in “classic” pages, it should be possible to use these new web parts everywhere. However, since classic pages use the old web part gallery and picker, it could be that we need to export and import one of these web parts to add them to a classic page.

General notes on news:

  • When a news page is created, it gets displayed on the site *immediately* in the “News headlines” and “News list” controls – no waiting for a search crawl
  • It’s important to click the “Add” button next to news to create a news page. Otherwise you’ll get a modern page, but it won’t show up as news - because it isn’t a news page. As Elio points out in What makes a page be a news page in SharePoint Online?, news pages have a field called Promoted State and the value gets set to 2. So that PromotedState=2 is the thing that identifies news pages
    • Note that this isn’t exposed in the UI, so there’s no easy way (outside of code/PowerShell/tool) to update this once a page has been created (at least for now)
  • Images uploaded during news page creation go into Site Assets/Site Pages/[escaped page name], like this:

     SNAGHTMLf13e9a2

So that’s a sense of how team news works in team sites. But what if you want to search/query for these pages as a developer or power-user?

Searching for modern pages and news pages

Searching for news pages

The main thing I wanted to say here is to extend Elio’s message and say that there is also a Managed Property with the same name (“PromotedState”), and so we can use search to find these pages too (e.g. if we wanted to roll-up team news from many sites):

image

..and so with a Content Search web part or similar, we can use this in a simple query to find results:

SNAGHTML16154ef2

For now it seems only news pages use this property, but it might be wise to add a filter on say, content type, in case Microsoft decide to use it elsewhere in the future.

Other notes:

  • The content type is the same for standard modern pages and news pages – here are the details:
    • ContentType (name) = “Site Page”
    • ContentTypeId = 0x0101009D1CB255DA76424F860D91F20E6C411800D294F66E48650D4DB0D1477463DC0B51
  • Data for all web parts is stored in one page field in the content type, and that translates to one managed property in search – here are the details:
    • Field name = “CanvasContent1”
    • Managed property = “CanvasContent1OWSHTML”
    • Sample data:

      SNAGHTML16253821

So, this idea that everything is stored in one field can potentially be a challenge with modern pages. It’s not going to be easily possible to query/filter on something that’s stored in the page because the data isn’t broken out into separate fields on the content type as we might normally do in a publishing scenario (e.g. show me news articles where category = ‘Politics’). That’s just a trade-off that comes with the flexibility and simplified page editing experience of modern pages I guess – I’m not sure Microsoft had too many options there.

The JSON response from the _api/sitespages/pages/feed endpoint (which the news headlines/news list controls use behind the scenes) looks like this:

Summary

The new modern pages are here, and the "team news" feature in team sites is one example of their use. Developers and power-users will find it useful to understand what things look like underneath, and for news pages it's the PromotedState=2 field value (and managed property) that identifies them. Thanks to Elio for pointing out the field value, and consider also the managed property which may be useful to you in search.

Tuesday 1 November 2016

Pitfalls when developing with the SharePoint Framework–my talk at Unity Connect, Amsterdam

UnityConnectIn a few weeks I’ll be speaking at the Unity Connect conference in Amsterdam, 17-18 November 2016. I’m looking forward to this event! There are some great speakers there such as Waldek, Spence, Dan Holme, Scot Hillier, Marc Anderson, Neil Hodgkinson and many others, and I think now is a great time to be talking about SharePoint and Office 365 – regardless of which aspect of it you work with. Certainly for developers it’s pretty good – many of us have got past the initial learning experiences of working with the SharePoint Framework (SPFX), but at the same time it’s a deep topic, and there’s lots still to learn and preferred approaches to work out.

In my session, I want to convey some of the mistakes you can easily make when getting started with SPFX. Between the coding side and the packaging/deployment side, there are definitely a few little traps in there – some articles which I think are great have been published so far, but I think it’s an evolving list and there a couple of things on my mind for sure. I’m also delivering a 20 minute “innova” session on developing a web part in the SharePoint Framework.

Here are the details of my sessions:

Avoiding common pitfalls when developing with the new SharePoint framework - Thursday, Nov 17, 13:20

Getting started with the new SharePoint framework can be a challenge initially. Whether you choose to use every JavaScript framework under the sun, or keep things as simple as possible, there's a reasonable amount to learn. Inevitably you'll fall into a few gotchas, and this session discusses the common ones to ensure you get to productivity fast. From adding JavaScript libraries to dealing with async code, from implementing TypeScript modules to dealing with npm, this session tries to smooth over your learning path.

INNOVA (20 minute session) : Developing a Client Web Part in the SharePoint Framework – What You Need to Know - Friday, Nov 18, 11:45

Creating a client web part in the new model is *very* different to the classic SharePoint web part experience that developers are used to. From creating the initial files with the Yeoman Generator, to adding your code in TypeScript, and then packaging for deployment – there are new things to learn at every turn! But there are huge advantages to the new approach – a better experience for users working with the web part, better performance, and freedom to develop using modern web technologies. Your JavaScript code can also be hosted wherever you like (e.g. a CDN), and this opens up some new options which are very welcome in the SharePoint world. This discussion and demo session looks at the fundamentals of client web parts so you can get an accelerated start on this important developer topic.

The conference

Anyway, there’s still time to register for the conference if you’re interested. Looking at the sessions and the price (€699), I think it’s a bargain personally. Go to https://www.unityconnect.com/2016/Registration to find out more

Friday 30 September 2016

Slide deck – Modern sites and the SharePoint Framework

Just a quick post of the slide deck I used for my talk last night at the SharePoint User Group. I talked about the changes for “modern sites” in SharePoint, and looked at things from the end-user and developer point of view (with respect to the SharePoint Framework). The link to the full deck is below.

I used this slide to speculate why I think Microsoft are motivated to change things like the “create or edit page” experience in SharePoint Smile

The Mum test

What I’m getting at is that many end-users (especially those who only use SharePoint occasionally) struggle with the current experience - using the ribbon, adding and configuring web parts and so on. Things are just too damn hard for SharePoint newbies.

And so we have a new set of web parts, and a new page editing experience. New web parts include the Highlighted Content web part, a PowerBI web part, a Yammer Embed web part, Office 365 video, and simplified text/image editors.

image 

image image

 

Slide deck

Wednesday 21 September 2016

Web part properties – dynamically populate Dropdown options in SPFx

UPDATED FOR SPFx RC0 – JAN 2017

When building web parts in the SharePoint Framework (SPFx), there’s often a need to implement custom web part properties – this allows the user to configure your web part in the way they need. Microsoft provide a set of core controls to use for this, one of which is the dropdown control (PropertyPaneDropdown). My previous article covered the basics of using the dropdown control (and others), but sometimes you need to go beyond providing a static ‘hard-coded’ set of options in the dropdown – in this post, we’ll show how to populate the control dynamically.

For reference, this article is part of the following series around web part properties:

Recap - populating the Dropdown control with static options

As a reminder, to provide a simple static list of options we use code like this in the getPropertyPaneConfiguration method:

PropertyPaneDropdown('dropdownProperty', {
                  label: 'This is the label',
                  options: [
                    { key: 'Red', text: 'Red' },
                    { key: 'Green', text: 'Green' },
                    { key: 'DarkBlue', text: 'Dark blue' }
                  ]
                })

But as we’re saying, having a static set of options often isn’t enough – we need to fetch them from somewhere when the user edits the web part. So let’s move on to that.

Dynamically populating the list – a simple example

Let’s start simple – in the code below, we change things so that the options are fetched from a separate method. I’m just showing the basics of using code to populate the list, but so far we’re not talking to SharePoint or another data source to get them:

So, we’re simply building an array of the appropriate object (IPropertyPaneDropdownOption) and returning it.

Dynamically populating the list – by fetching data from SharePoint

Things get a little more complicated when we need to talk to SharePoint, or make some other kind of async call to get the data. If we simply amend the previous code to call SharePoint (using spHttpClient or similar), we’ll find that we may have timing issues – our async method will fire, but getPropertyPaneConfiguration method continues to execute during this time, and the collection of items is empty. Some time later the collection will be populated, but it’s too late for our dropdown control.

The trick is to obtain the data, and then refresh the property pane by calling the onDispose() method of the web part. This patterns ensures that you are not delaying the load of the entire page or web part property pane, but that the UI is refreshed once the dynamic data has been fetched.
 
NOTE: in previous SPFx builds, the guidance was to use the OnInit() method of the web part – however, that led to problems in some scenarios, so that guidance has been updated to the pattern described here. For other things, OnInit() can be your friend though – just not necessarily for web part property pane work.

In this example we populate the dropdown with the SharePoint lists in the current site. We do this with an async REST call to SharePoint, which uses Promises in the code structure:

..and then in the getPropertyPaneConfiguration method, we kick-off the call to fetch the data at the beginning, and then in the control declaration we simply set the options property to our variable holding the array:

So that’s it – a web part property control using dynamic options!

Summary

The web part property model in SPFx is quite powerful, and is a great advantage of the SharePoint Framework compared to the classic “cloud-friendly web part” approach of using a Script Editor and some JavaScript. It’s possible to run code to build your web part property pane, but just be aware of timing and lifecycle issues. The onDispose method in a SPFx web part can be used to refresh the property pane once any additional code you have has executed.

Monday 19 September 2016

Speaking at SharePoint User Group UK – modern sites and the SharePoint Framework

SUGUKI’m looking forward to speaking next week at the UK user group (SUGUK), in my backyard here in London. It’s a time of pretty big change in the SharePoint world, and since the user group is typically a mixed audience I thought it would be useful to consider things from more than one angle – after all, the changes will affect a BIG cross-section of people and roles. I’m thinking mainly of the changes being rolled out to team sites and publishing sites this year, but of course these fit into a wider context of Office 365 Groups, PowerApps, and a whole list of things, so we should think about it in those terms. And of course, I will be covering some developer aspects and showing some SharePoint Framework code – and hopefully having some good discussion off the back of all this!

Here are the details:

The blurb

Here’s the title and summary for my talk:

Modern SharePoint sites and the SharePoint Framework
Microsoft have started releasing their big wave of changes to SharePoint sites in Office 365 ("modern" sites). This affects end-users in terms of user interface changes, but developers too with the introduction of the SharePoint Framework. In this session we'll consider both perspectives - we'll take a quick look at some of the changes in SharePoint Online team sites (including those which have not yet landed), including a look at "modern" page editing and the new set of web parts Microsoft are working on. We'll also consider how this affects on-premises SharePoint going forward.

From there we'll switch to a dev perspective - we'll build a web part in the SharePoint Framework, and start exercising our TypeScript, Gulp, and npm knowledge. It's a brave new world, but if you want your web parts to work in the new user experience you have to get on board!

Hope you can make it there if you’re local!

COB.

Tuesday 13 September 2016

Web part properties in the SharePoint Framework – part 1

Modern SharePoint pages have a new web part editing experience. This is powered by modern web parts and the new SharePoint Framework (SPFx), and developers who wish to work with these new pages need to understand the new model. As you start to build modern web parts, you’ll find the need to implement web part properties – so that your end-users can provide any options or settings required. Microsoft provide a set of common “property pane” controls such as textbox, dropdown, slider and so on – and it’s also possible to add an entirely custom control (something I’ll cover in a future article). In most cases the core controls are your starting point though, so in this article I’ll start looking at the TypeScript/JSON needed to use these controls.

First things first – reactive vs. non-reactive property panes

Perhaps the first thing to understand when implementing web part properties is that by default, the new page framework supports *immediate* changes to the rendering of your web part when a page editor changes a property. This is known as a “reactive” property pane - no more having to click “Save”, “OK”, “OK” just to see a change. Let’s take the example of a web part property specifying the description of the widget - if a user edits this in a textbox, and this is displayed in the main area of the web part, it will be dynamically updated as the user types. This happens automatically, although can require the developer to implement certain things in more complex cases.

Sometimes you want to disable this though – perhaps it’s not appropriate to have the UI constantly updating, or a lookup to SharePoint is needed each time there’s a change. You can disable the reactive behavior by adding this code to your web part class:

protected get disableReactivePropertyChanges(): boolean {
    return true;
  }

 

Structuring web part properties into pages and groups

Perhaps the second thing to mention is that the new web part property pane can be structured into multiple pages, each with groups of properties. And the best news is that we don’t have the baggage of the old web part properties on every single web part that no-one ever used (“Allow Minimize”, “Allow Close” etc.). So in the new world, a simple web part property pane with a couple of pages and groups might look something like the images below – take note of the page title, group title and paging controls:

SNAGHTML61509e7e

This allows us to better structure our properties, and so in my example the page 2 of the web part props might look like this:

SNAGHTML6152c7e6

You can continue to define additional pages and the framework will take care of providing paging in the UI for you. In terms of the code to do this (and define SPFx web part properties in general), all the action happens in the getPropertyPaneConfiguration() method. Here’s the code for the above (by the way, I’m using Gist for longer code samples like this one but have others “inline” in the post, so apologies that they look slightly different!) – anyway, we basically have two pages being defined in our structure now:

Using the different controls

So now we understand how to split our controls into pages and groups, let’s move on to the controls themselves. The first step in editing your web part code is to add import statements for TypeScript modules – we do this for each control we wish to use. So at the top of your web part class, move from something like this:

import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  IWebPartContext,
  PropertyPaneTextField
} from '@microsoft/sp-webpart-base'

..to..

import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  IWebPartContext,
  PropertyPaneTextField,
  PropertyPaneCheckbox,
  PropertyPaneChoiceGroup,
  PropertyPaneDropdown,
  PropertyPaneSlider,
  PropertyPaneButton,
  PropertyPaneToggle
} from '@microsoft/sp-webpart-base'

From there, we can start expanding the code in the getPropertyPaneConfiguration() method. We saw how to divide up our properties into pages and groups in the earlier code sample, but to zoom in on that for a second, here’s a specific change to move from the default arrangement to something with a second group. So we would move from the default of this:

groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
         ]

..to..

groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            },
            {
              groupName: "COB settings",
              groupFields: [
                PropertyPaneTextField('query', {
                  label: “Query” 
                })
              ]
            }
         ]

As with any JSON, you have to take care with closing brackets and braces! Note that for simplicity/illustration, you can see I’m not putting my strings such as the groupName and control label text into the separate strings class here – but in real life I recommend doing this to avoid magic strings littered through your code.

So, structuring your properties into pages and groups is pretty simple. Now let’s start looking at the individual controls – I’ll look at some here, and some in future articles.

Text box (PropertyPaneTextField)
Properties:

Property

Description

label Label shown next to the control.
description Description shown next to the control.
value Value in the field – can be used to set default text.
ariaLabel A non-visible label – used by accessibility-focused tools and browsers, as per the ARIA standards.
multiline Specifies whether the textbox is multiline (boolean).
placeholder Allows you to provide default placeholder text, shown when the control has no value.
resizable Specifies whether the control can be enlarged by the user (to make it easier to enter larger amounts of data).
underlined Whether or not the textfield is underlined.
errorMessage A static value for the error message – it’s not clear to me when you’d use this, because the error is always displayed. The onGetErrorMessage property is what you’d really use it seems..
onGetErrorMessage Pointer to function to use for validation – returns either a string (containing the error message) for simple cases OR a Promise<string> for more complex cases where you need to make an async call to SharePoint (or similar) to do the validation.

See below for more details.
deferredValidationTime Amount of time (milliseconds) to wait before showing the validation error message – e.g. to allow the user to finish entering a value.
The code:

Note that I’m also showing a simple textbox validation routine in the code below – note the onGetErrorMessage usage:

PropertyPaneTextField('textboxProperty', {
                  label: 'This is the label',
                  multiline: true,
                  resizable: true,
                  onGetErrorMessage: this.simpleTextBoxValidationMethod,
                  errorMessage: "This is the error message",
                  deferredValidationTime: 5000,
                  placeholder: "This is the placeholder text (shown when no value is entered)",
                  "description": "This is the description"
                })

private simpleTextBoxValidationMethod(value: string): string {
    if (value.length < 5) {
        return "Value must be more than 5 characters!";
    } else {
      return "";
    }
  }

What it looks like:

SNAGHTML4d5ddb9f

..and showing a more real-life example once the validation function has executed:

SNAGHTML4df82741

More advanced validation for the text box control

So in the example above, I showed a simple function to check the value the user entered was more than 5 characters. But what if you want to talk to SharePoint, or make some other async call to validate text box contents? In this case our function referenced in onGetErrorMessage must return a Promise<string> rather than a string – and things are a little more complex due to needing the right context for ‘this’ in your function. Here’s an example of an async textbox validation method – I’m checking if the value entered matches a list in the current site:

But there’s more. Initially I was getting errors indicating that ‘this’ was undefined in my function – manifesting in a ”Uncaught TypeError: Cannot read property 'context' of undefined” error as I was trying to access this.context in my web part code. So why was ‘this’ not populated? The answer is that it just isn’t with a default function pointer here. To get around this, we need to use the JavaScript/TypeScript ‘bind’ method. This allows a new invocation of the function where we can pass ‘this’ as a parameter – the receiving function then has the context. So where we reference our function in the onGetErrorMessage property of the textbox, instead of this:

onGetErrorMessage: this.asyncTextBoxValidationMethod,

..you need this:

onGetErrorMessage: this.asyncTextBoxValidationMethod.bind(this),

Big props to my colleague and friend Vardhaman for this – he has a great article on this specific subject (before the official docs mentioned it), and it’s there that I discovered this solution. Thanks Vard!

Checkbox (PropertyPaneCheckbox)
Properties:

Property

Description

text Text displayed next to the checkbox.
checked Specifies if the control is checked.
disabled Specifies if the control is disabled.
Code:
PropertyPaneCheckbox('checkboxProperty', {
                  text: 'This is the text', 
                  checked: true,
                  disabled: false 
                })
What it looks like:

SNAGHTML4e0dbd03

 

Dropdown (PropertyPaneDropdown)
Properties:

Property

Description

label Label displayed next to the control.
options An array of IPropertyPaneDropdownOption objects (similar to HTML <option> tag – defines the key/text etc. of the option). Can be specified in a static way, or fetched dynamically – see my other post (coming soon!) for details on this.
selectedKey Key name of the selected item. Can be used to set the initially-selected item.
disabled Specifies if the control is *disabled* (not sure why this is flipped the other way compared to other controls! Hopefully this will be made consistent in future releases..)
Code:
PropertyPaneDropdown('dropdownProperty', {
                  label: 'This is the label', 
                  disabled: false,
                  options: [
                    { key: 'Red', text: 'Red' },
                    { key: 'Green', text: 'Green' },
                    { key: 'DarkBlue', text: 'Dark blue' }
                  ]
                })
What it looks like:

SNAGHTML5c0d42aa

Summary

Building web parts in the SharePoint Framework brings a few new things, including a new model for web part properties. This is where the framework shines compared to other techniques like using a Script Editor web part and a separate JavaScript file – that method simply did not provide a way to use custom properties. In this post we looked at the first few of the controls, and also noted that populating a dropdown dynamically needs a specific approach which I detail in another article.

In future articles, I’ll look at other out-of-the-box web part property controls.

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.

Friday 1 July 2016

Understanding the web part manifest, bundle.json and other key files and folders in the SharePoint Framework

The new “SharePoint Framework” model for client web parts and client-side applications uses a whole series of files that developers must learn to successfully extend SharePoint using this approach. There is a new web part manifest file (now in JSON rather than XML) and files such as bundle.json, package-solution.json and upload-cdn.json which interact with the new Gulp-based developer tools to control how the solution is packaged and deployed – all wrapped up in a new folder structure. So, there’s a learning curve and understanding these files and folders is crucial. In the previous post Develop a client web part in the SharePoint Framework - a walk-through we looked at the overall “getting started” process which creates the files for you using Yeoman Generator – but in this article I’ll explain the files and folders.I

Folders used in the SharePoint Framework

Let’s start with a rundown of the various folders and what they contain. My last post had a cut-down version of this table, but I expand on the descriptions here, and add a list of key files and an image so you can see what that folder looks like:

Folder

Purpose

Key files

Image

src The place where you add/edit code files – you will build up your structure of files here.
  • [MyWebPart1.ts] (TypeScript)
  • [MyWebPart1.manifest.json]
SNAGHTML72de5c5_thumb
lib Contains “processed” code files which are ready to move into the bundle which is distributed with the app.

For example, TypeScript files have been compiled to JavaScript files in this directory.
  • [MyWebPart1].js
  • [MyWebPart2].js
SNAGHTML72e6ac4_thumb
dist Contains the final code files which are distributed with your application.

The most important file is the final JavaScript bundle file  [MyWebPart].bundle.js – this is all of the JS for your web part, including some framework stuff.
  • [MyWebPart].bundle.js
  • [MyWebPart].bundle.js.stats.json
  • webpart.manifest.js
SNAGHTML4ed93fd_thumb
config Contains a set of JSON files used by the tooling for the build process. In particular to control how your app is packaged - in terms of the .spapp file, JavaScript/CSS bundling and so on.
  • build.json
  • bundle.json
  • package-solution.json
  • serve.json
  • upload-cdn.json
SNAGHTML4e02bfb_thumb
node_modules Contains JavaScript modules used by the solution. TypeScript follows the standard set by node.js for resolving modules (i.e. when you use the import keyword to use an object defined in another module/library), and the node_modules folder is a key part of this.  Whatever JavaScript libraries your code OR the underlying SharePoint Framework has a dependency on. SNAGHTML73042df_thumb
typings Contains TypeScript typings files – these are used to give you auto-complete (IntelliSense) against JavaScript libraries you are using, such as jQuery. Typings for whatever JavaScript libraries you’re using in code. These typically get added with TypeScript Definition Manager with e.g.
tsd install jquery jqueryui --save
SNAGHTML14200135
sharepoint Contains the .spapp file which is generated by ‘gulp package-solution’. This is what you’ll add to the App Catalog of your real environments such as production.

Also has a ‘debug’ folder so you can see what went into the package.
  • [MyApp].spapp
SNAGHTML20029fca

The web part manifest

The [MyWebPart].manifest.json file is where core details such as the display name and description are specified. Critically, other associations are specified here such as the associated JavaScript file (usually a bundle) and any dependent JavaScript modules which will be loaded – yes, there’s an in-built JS loading framework for you. Here’s a rundown of some key properties specified in the manifest.json file:

Element

Sample value

Purpose

ManifestVersion 1 Represents the version of the manifest schema that the build system is expected. Currently this must be “1” – any other value will be rejected.
id 41d9c141-e10f-4373-8a24-84383fa95592 ID of the client web part – the same as we’re used to, i.e. it provides a concrete way of identifying a web part (e.g. through APIs)
bootstrapModule http://localhost:4321/dist/cob-latestnews-wp.bundle.js

https://cob.azureedge.net/intranet/cob-latestnews-wp.bundle.js
This is where the JS file for the web part lives. In dev, you’ll have a localhost path (which the tooling hosts for you using node.js). For production, you’ll replace this with the path where you deployed the JS file to for real – a CDN, website path, or similar.
moduleName CobLatestnewsWebPart JavaScript module name of the web part object.
localizedScripts ? I believe this is an array of locale/JavaScript file mappings – to support localization.
preloadModules

"preLoadModules": ["jquery","jqueryui"]

Specifies JavaScript modules that the web part should load before execution. The module names specified here must match names/paths specified in the “config” element described next – in other words, you name the module and specify where it’s loaded from.
config

"config": {
        "paths": {
            "jquery": "//code.jquery.com/jquery-1.10.2.js",
            "jqueryui": "//code.jquery.com/ui/1.11.4/jquery-ui.js"
        },
        "meta": {
            "jqueryui": {
                "scriptLoad": "true",
                "deps": [
                    "jquery"
                ]
            }
        }
    }

Used to specify paths to JavaScript libraries pre-loaded by the web part (as specified in the “preloadModules” tag). Dependencies between scripts are also specified here - so that jQuery is loaded before jQuery UI for example (shown left).
properties

"properties": {
    "description": "Displays recent docs for the current user.",
    "headerText": "Your recent documents:",
    "searchQuery": "*",
    "itemLimit": "5"
  }

Specifies default values for web part properties. Note that other elements of web part properties are defined in the web part code – specifically the interface which represents the web part’s properties, and the propertyPaneSettings method. You can see these in the code sample above.

Note that there are other properties in the manifest file which I’m not listing here – but these are some important ones for now!

Other key files in the “src” folder

In addition to the web part manifest, files your code files also live here. These other files here can be summarized more easily, so I’ll switch to bullet points. You will create sub-folders in here, and build our your codebase as you need. But let’s take the example of single web part, and look at the set of files used:

  • [MyWebPart].test.ts – a file to add Mocha JavaScript tests to
  • [MyWebPart].less – a file to add LESS CSS directives to. If you’re not familiar with LESS, it’s a way of structuring CSS in a neater way – it allows variables (e.g. @cob-title-color: #FFB900; – which you can then use in different styles). In addition to variables, CSS markup can be nested in a way which matches HTML structure. Both of these things make your CSS code easier to maintain.  See http://lesscss.org for more details.
  • [MyWebPart].strings.ts – a file to add resource strings to (to keep them in a separate place from your code, and therefore avoid magic strings)

Files in the “lib” folder

The lib folder serves as an intermediate folder in the build system. A few things happen between the src and lib folders:

  • TypeScript files get compiled to JavaScript files
  • LESS files get compiled to CSS files 
  • CSS files get minified, and prepared for the CSS loader
  • HTML templates files get compiled to JavaScript (N.B. I’m still working that one out!)
  • TypeScript typings files are generated for each of your .ts files (i.e. “foo.d.ts”, as per the TypeScript convention)

Files in the “dist” folder

These are files which are distributed with the app – several of these are used at run-time for example:

Key files:

  • [MyWebPart].bundle.js – this is all the JavaScript required to run your solution, and is CRUCIAL to your web part or client-side application working properly. When you package for production, you can host this file anywhere you like (CDN, Azure web app, on-premises web server etc.) but whatever URL it lives at must be reachable by end-users AND it must be specified in the “bootstrapModule” key in the web part manifest.
  • [MyWebPart].bundle.js.map – map file to support browser debugging
  • [MyWebPart].manifest.js – this is the shipped version of your web part manifest file.
  • [MyWebPart].bundle.js.stats.json – a file which contains metadata about the generated JS bundle. One really useful thing in here is the “modules” node, which lists all the original JavaScript files which went into the bundle. This is really useful if you’re troubleshooting why a JavaScript library you’re using isn’t making it’s way into the bundle (or vice-versa) – much easier than trying to read the uglified JavaScript in the bundle itself (and trying to work out where jQuery stops and jQuery UI starts for example!).

Files in the “config” folder

The config directory holds a collection of JSON files which mainly control how the app gets packaged. The most critical files are:

  • bundle.json – this controls which JavaScript files make their way into your final JS bundle. Note that by default, any 3rd party JS libraries you load as a module into your code (e.g. with something like import $ = require('jquery'))  will get included into the bundle. However, you can override this (for example if you’re referencing jQuery on a CDN) by adding an “exclude” entry with the same name. More on this in another article.
  • package-solution.json – controls the details of the app package which is produced by gulp package-solution. This is the .spapp file that you’d upload to the App Catalog to make the web part available when packaging for a non-dev environment
  • upload-cdn.json – I’m unsure if this will be in this form in the final toolchain at release time, but this file provides a convenient way to push files (e.g. your JavaScript bundle) to Azure file storage (and optionally Azure CDN, if you’ve configured that). The file takes parameters which identify your area in Azure BLOB storage so the files get uploaded to the right place, such as:
    • account
    • container
    • accessKey

Bundle.json is an important file, especially as you add multiple JavaScript files and reference more and more external libraries. I’ll dig deeper into this one in a future article, but for now let’s just consider a couple of key points. Here’s what bundle.json looks like in the current tooling:

The “entries” node specifies elements of your solution – for example each JavaScript file which should go into the bundle. Notably you can have 3rd party JavaScript libraries bundled in with your JS code if you like – in fact, you have to explicitly exclude them if you they are used as a module in your solution but you’re referencing a CDN at run-time for example. The key children of the “entries” element are:

Element

Sample value

Purpose

entry “./lib/webparts/cobLatestnewsWp/CobLatestnewsWpWebPart.js” Path to a source file to go into the JavaScript bundle. The “lib” folder is expected to contain JavaScript files, not TypeScript files – any TS files in the “src” folder are compiled to JavaScript files which are output here (think of gulp.dest() if you’re familiar with it).

However, it is not the final bundle of all JavaScript files - that is the one generated into the “dist” folder.
outputPath "./dist/cob-latestnews-wp.bundle.js" Path to the final JavaScript file for the entire bundle. This is what will be distributed with your app and what end-users will hit. 
exclude

"@ms/sp-client-platform",
  "jquery"

Modules used which should NOT go into the bundle (e.g. because you’re referencing jQuery [for example] on a CDN).

Files in the root folder

And finally, we get to files in the root folder. Several important files live here, such as gulpfile.js which is the entry point to the build system – you might choose to extend this to add custom Gulp tasks. The following list details the key files:

  • gulpfile.js – the “top” of the build system, and this defines the Gulp tasks you call from the command-line such as:
    • gulp build
    • gulp bundle
    • gulp serve
    • gulp package-solution
    • gulp upload-cdn
    • [N.B. the Gulp tasks themselves are defined within the node_modules\@ms\ms-core-build\tasks folder]
  • package.json – similar to “packages.config” in NuGet, in that it defines the JavaScript library dependencies (and their versions) used by your solution.
  • tsconfig.json – defines TypeScript compilation settings
  • tslint.json – defines TypeScript style checking settings

Summary

Phew! As you can see there are lots of new files and folders to get to grips with in the SharePoint Framework. Remember that this information is based on an early version of the Framework, and there may be some changes by the time things actually become generally available – I will update this post with any changes I find to keep the information accurate. I’ll also be covering more aspects of the SharePoint Framework in the next few articles.