Thursday, 19 January 2017

Avoiding dependency issues in SharePoint Framework (SPFx) development

One area I talk about in my “Avoiding pitfalls when developing with the SharePoint Framework” talk is dependencies, and the problems you can run into. Whether you depend on jQuery, Angular, React or other JS libraries is up to you, but there will always be some – and npm is typically the way to bring these libraries into your SPFx solution. Using a TypeScript/JavaScript-based code stack and npm packages is completely different from .NET, and I think most SharePoint developers are fairly new to this world. There’s quite a lot to learn with npm itself, but this is important for successful team development with SPFx. Of course, npm, gulp and node.js might be familiar territory if you’ve already done lots of modern JS-focused web development (by which I don’t mean jQuery!), but there are deep topics here beyond just the coding aspect.

To get the development and ALM process right with SPFx, some of the answers lie in use of commands like npm shrinkwrap, having a solid understanding of the package.json file and how developers specify different types of dependencies. But before we get to that in detail, let’s start by talking about the problems and some general background to understand.

I use the slide below to summarise some key pitfalls in this area, splitting them into “dev” and “shipping” considerations:

clip_image002

What are caret dependencies (never mind why they can be a pitfall)? What does –save do on the npm install command? If those are questions you’re asking right now, then my companion post SPFx - an overview of node_modules, package.json and other node concepts might be useful.

Otherwise, let’s get to the detail.

Not specifying --save on npm install

This is a newbie pitfall for teams/developers not very familiar with npm. When a developer adds a package with npm install, the package is downloaded from the npm repository and installed to your application – at least, in the machine and folder that the command is run on. Adding the --save flag ensures the dependency is also recorded in package.json – thereafter, when any dev runs npm install or npm update for this application, npm will again ensure the appropriate package is downloaded and installed locally (because the package.json file is shared via source control). It’s the equivalent of adding a .NET dependency via NuGet, compared to just adding a local file reference. As ever, checking the full set of packages themselves into source control is usually a bad idea. So, the pitfall is simple - if the dev forgets to use the --save flag when installing a package, no entry in package.json is made and code may fail due to a missing library on other machines. You’ll see a TypeScript compile error like “Cannot find module” when another developer tries to build or run the code (e.g. with gulp serve):

clip_image004

Recommendation – always track your dependencies by specifying the --save parameter (or one of the options such as –save-exact) when running npm install.

You might also consider a custom .npmrc file for your team here, which can automatically specify certain parameters (e.g. --save or --save-exact) without the dev having to remember them. I talk about how a custom .npmrc file works in the other post.

N.B. if you do fall into the trap of using a dependency without it being properly stored in package.json, simply install it again *with* the --save (or similar) flag. Then have each dev run an npm update to ensure everyone is using the same version.

Pitfall - using caret dependencies without thinking about it

When adding an npm package, the default is to use a caret dependency. However, both caret and tilde dependencies bring an element of risk to the dev process (but can have benefits too). If you’re not familiar with version numbers which use carets or tildes, read either my background post or semantic versioning (semver) in the npm docs.

Briefly, the caret character (^) denotes that any version up to (but not including) 4.0.0 is acceptable. Caret dependencies like this are the default with npm, but can lead to danger because there can be all sorts of changes within that version range, potentially including breaking changes, depending on how the package author handles things. Not everyone plays by the semver rules. So, that means that in team development, one person on the team can be using 3.1.1 and another 3.9.9 (i.e. releases of the same major version, but different minor versions), depending on how when each last ran the npm update command. So, there can be lots of variability from caret dependencies like these.

Tilde dependencies (~) are similar, except here the range is more narrow – so ~3.1.1 would allow any version up to (but not including) 3.2.0 (i.e. releases of the same major/minor version, but different patch versions).

Note also that I’m simplifying things here slightly, since npm deals with things differently when a zero is used in the version number. See the semver page for more details.

So are caret and tilde dependencies always bad?

Well no, not really. You might decide that you DO want the latest and greatest of libraries you are using during the dev process, without the hassle of managing each individually. Often you do indeed want those minor bug fixes and performance enhancements – and avoiding “exact” dependencies gives you that (so long as you npm update regularly).

Recommendation – make an explicit decision about whether you want “floating” dependencies in dev.

If NO, consider these options:

  • Ensure all developers always use the –save-exact flag instead of the –save flag
    • This will have the effect of writing in an exact reference into package.json, rather than a caret or tilde dependency
    • Use a custom .npmrc file across the team to have the same effect (without developers having to remember –save-exact every time they install a package)
  • Again, see my SPFx - an overview of node_modules, package.json and other node concepts for details on this technique

If YES, then:

  • Stick with caret dependencies, but consider becoming “tighter” as you approach releasing your web part – ensure all devs are running npm update regularly, and perhaps switch to exact dependencies just before shipping.

Whether you use exact dependencies in dev or not, there’s something that I recommend you always do to freeze dependencies at ship time of each release, and that’s to run npm shrinkwrap. We’ll talk about that next..

Pitfall – not locking down dependencies when you make a release

In SPFx and node.js development, it’s crucial to remember that the node_modules folder is an entire tree of dependencies. First level dependencies that you know about have their own dependencies, which are stored in child node_modules folders – that’s why the node_modules folder can be big in size and go quite deep. The steps we’ve talked about so far, such as considering use of --save-exact to avoid caret/tilde dependencies, only get you so far – and that’s because they deal with your first level dependencies only. Consequently, you’ll find it difficult to recreate the *exact* build you shipped as v1 because you can’t restore the exact node_modules folder you had at the time of this build. Sure, you could if you always checked the entire mode_modules folder into source control for every build, but yuck!

What you need is for the entire tree of dependencies to be frozen for each release – the npm shrinkwrap command gives you this. It creates a JSON file containing details of which version was resolved of every package used:

SNAGHTML9f2fa0f

Thereafter, if the npm install or npm update commands are used against a folder containing such a file (named npm-shrinkwrap.json), npm will look to it to restore the packages. This is different to the default behaviour which will use any caret or tilde dependencies (etc.) specified in the package.json file. Thus, with this approach you can restore the entire build as it happened at a certain time, without having the node_modules folder in its state at that time.

Recommendation – run npm shrinkwrap every time you release a version of your code. Store the npm-shrinkwrap.json in source control.

Summary

Creating SharePoint Framework solutions effectively involves more than just learning the new APIs. You need to build a good understanding of the underlying web stack, and arguably some elements are more important than others – modules, packages and npm is a combined area that I recommend spending time on. Without this, it’s easy to fall into some pitfalls when developing or shipping your SPFx solution. Overall I recommend:

  • Taking care when developers add libraries – ensure they are tracked in package.json
  • Deciding on whether you’re happy with floating dependencies during dev, or whether you prefer to use exact dependencies
  • Running npm shrinkwrap each time you release a version of your solution, and checking the npm-shrinkwrap.json file into source control. This will allow you to rebuild the app properly later on, when never versions of your dependencies have been released

SPFx - an overview of node_modules, package.json and other node concepts

N.B. this is a companion post to Avoiding dependency issues in SharePoint Framework (SPFx) development

Any SharePoint Framework (SPFx) solution that does something useful will use external JavaScript libraries – whether bigger frameworks such as React or Angular, or smaller, more focused libraries such as LoDash, moment.js or something else. Since SPFx is based on a node.js-based web stack, the best way to integrate such libraries into your solution is usually to add them from npm, the internet-based package manager for JavaScript. Npm is effectively an equivalent of NuGet in the .NET world. Once you’re set up with npm, a developer simply runs npm install jquery [or whatever] and the source code for the package will be added to your application’s files. As is normal with node development, the library is added under the “node_modules” subfolder, and it can now be referenced in your code.

The role of the node_modules folder

So the node_modules folder stores all your dependencies. But it also stores any dependencies of those, and so on and so on. So, it’s a tree structure which can be quite deep. An app which uses jQuery and React for example, could look like this:

clip_image002

In this example, jQuery has a dependency on “cache-swap”, which also has its own dependencies in its node_modules folder. And so on..

Modules which are actually used by your code are distributed with your app, so everything works at run time. The bundling mechanism built into the SharePoint Framework tooling takes care of this using webpack.

Ensuring dependencies are tracked with package.json

If the --save flag is also specified when adding a package with npm install, an entry is written into the package.json file in the application’s directory. This goes into the “dependencies” section of the file, and will look something like this:

"jquery": "^3.1.1"

Here’s an example of full package.json file:

clip_image004

Notice the caret (^) in that version number above. I’ll talk about tilde and caret dependencies later. But the purpose of that –save flag is is to ensure that the dependency is recorded. The node_modules folder itself is typically *not* checked-in to source control (in the same way all NuGet packages would not be), partly because it is large and unwieldy. Instead, each developer has a local copy on their machine, and the shared package.json file plays a critical role in ensuring all devs have the same files. When another developer subsequently obtains the files from source control, running the npm install or npm update commands will ensure all dependencies are restored on his/her machine, based on what’s stored in the package.json file.

As I detail in Avoiding dependency issues in SharePoint Framework development, if the developer forgets to track the dependency (with the --save flag or similar), then other devs are likely to be missing the module on their machines and the code will not work for them – they’ll get a missing module error. However, even if developers do always remember to specify the --save flag, you can run into problems in dev because npm uses caret dependencies by default, and these are a form of “floating version” dependency. I won’t discuss the pitfall further here, since we’re all about the fundamental concepts in this post – but related to all this is the whole topic of semantic versioning (known as semver).

A brief summary of semantic versioning

Semver refers to the different kinds of version numbers which can be used by npm packages. The semver page in the npm docs is recommended reading, but I’d say the core things you need to understand are:

  • The 3 part version number format i.e. MAJOR.MINOR.PATCH, and the rules for when each number should be updated – see http://semver.org
  • The different forms of version number used in package.json

Version number forms include:

Type

Example

What it does

Caret dependency

^3.1.1

Allows any version on the same major version, i.e. anything below 4.0.0

Tilde dependency

~3.1.1

Allows any version on the same minor version, i.e. anything below 3.2.0

However, my table above is a simplification because npm deals with things differently if there is a zero in the version number. Additionally, npm supports other forms too such as pre-release versions like “1.0.0-alpha.1” and tags. I recommend spending time in the npm docs, but there are LOTS of simplified posts on the internet too if you prefer another format e.g. https://nodesource.com/blog/semver-tilde-and-caret

Setting npm defaults to get consistency across devs

Elsewhere we’ve talked about parameters to pass to npm commands, such as the --save or--save-exact flags used with npm install. However, a useful approach with a dev team can be to set defaults across the team so that each developer does not need to remember a certain flag each time a command is run. This can be done in a couple of ways:

  • Setting environment variables on each machine
  • Using a .npmrc file – at the project, user or global level

I like the idea of using the .npmrc file at the user level (e.g. C:\users\chris\.npmrc on my machine), and ensuring all team members have this in place. By creating/editing this file, I can specify for example that all dependencies should be saved into package.json with *exact* version numbers, rather than caret or tilde dependencies. I can do this by adding the following to my file:

save = true
save-exact = true

Now, when any dev installs a package, the following differences to the default behaviour will occur:

  • The dependency will automatically be added to package.json, even if the dev accidentally forgets the --save flag
  • The dependency will be added with an exact version number, not a caret version number

This is useful, as devs won’t accidentally fall into some of the pitfalls that can come about from the npm defaults.

Also check out the save-prefix config flag as an option to override caret dependencies (e.g. to change to tilde dependencies).

Summary

Hopefully this is some useful background information to concepts underneath the SharePoint Framework. It can seem a whole new world in some respects, but at the same time I don’t think you have to be a complete expert in npm, modules, webpack etc. to be productive. A little extra digging around sub-topics like these is recommended though I think. Have fun!

Thursday, 5 January 2017

Changes to Custom Actions and handling of JavaScript in SharePoint Online

Recently our Custom Actions stopped working in modern document libraries in Office 365. We were surprised at this, because as far as we were aware we weren’t doing anything that went against “new” guidance for working with modern team sites and modern document libraries. Since the beginning of modern doc libs, Custom Actions which use ScriptSrc or ScriptBlock have not been supported (same with JSLink customizations). But we weren’t doing any of these things – our specific details were:

  • A Custom Action using a URL-based action which opened a modal dialog (pop-up) – in our case, to show a custom options page to the user
  • Use of “EditControlBlock” as the location, so our menu item appears on the context menu for each document
  • Registered on our “base document” content type which is used in our document libraries

And for a while everything was great - as expected, our menu item showed up in both the classic and modern document library experience. However, in early December (2016) our menu item disappeared from the modern experience, across all our tenancies (eventually). These images show our menu item (named “Actions”) visible in the classic view but not modern:

Classic:

Classic_

Modern:

Modern_

New rules for Custom Actions

Essentially, Microsoft have made changes in exactly what is supported with Custom Actions. I guess you could say this doesn’t align 100% with previous guidance on the topic – or at least, some low-level details were ambiguous or open to interpretation. For example, the Update on Modern Document Libraries and Extensibility blog post says this:

“We’ve already made some good progress here.  Theming, global navigation links, and URL-based custom actions that extend the ribbon and context menus are already supported in the modern document library experience.  This ensures that customers and partners taking advantage of these features can use the modern document library experience without compromising their customizations.”

For our part, we figured that we should be fine because we’re using a URL (rather than ScriptSrc or ScriptBlock). However, talking with the Office 365 engineering team, it became clear that a URL which contains JavaScript (e.g. Url=’javascript:OpenDialog()’) is no longer permitted – although this did work until early December. Additionally, targeting by content type no longer works – the only option currently is to target by list template type, for example:

  • 100 – custom list
  • 101 – document library
  • ..and so on

UPDATE – targeting by content type now works again. So you can once again target by content type or list template type..

I appreciated the help from folks in the product group who helped me understand what their code is currently doing, and where things might head in the future – thanks guys.

Anyway, we had to make some changes. In our case, since we can no longer open a dialog from the menu (since that requires some JavaScript), we’re changing our experience to navigate the user to a full page instead. Also, we need to change the targeting from content type to list template type – that’s mainly OK, but in truth does give us a slightly different scope to what we really wanted.

Could any of these changes affect you? If so, you’ve probably noticed already – but either way, it’s definitely worth SharePoint developers becoming clear on the latest developments in this space. Overall, there is a longer list of these kind of things which are no longer supported on modern lists and libraries, including:

  • Custom master pages
  • JSLink (field and view types)
  • AlternateCssUrl
  • Custom Actions which use ScriptLink to add JavaScript to the page

On the bright side, there is now some official documentation in the form of MSDN articles which provide more detail than I’m including here. I highly recommend going through these:

Using the classic experience as a workaround

Remember of course that these changes don’t affect the classic experience. You have the choice of continuing to use that (e.g. by setting it at the tenant level) if you’re happy with that. We weren’t unfortunately, because we want our uses to have the benefits of the new document library UX (better mobile experience, improved metadata editing, new summary panel, sorting/filtering enhancements and so on).

Looking to the future (especially around JavaScript in Office 365)

Microsoft have noted in several places that new mechanisms will come to SharePoint Online to match many of the previous capabilities. They may not take exactly the same form as the previous mechanisms, but it should be possible to achieve the same overall result. These include:

  • Custom master pages --> some other “deep branding” controls (which may or may not provide the ability to control the full HTML)
  • JSLink --> some other mechanisms to control the rendering of list views and fields
  • CustomAction + ScriptLink --> some other mechanism to add JavaScript to pages

Thinking specifically about JavaScript, I think it’s clear that there will be increased controls around administrator approval of scripts – the idea is to provide more governance so that arbitrary scripts cannot be added by a developer without wider approval. After all, that’s why Microsoft have made some of the recent changes to pull back on previously supported approaches – they did leave holes which could result in trouble for some organizations. Despite the occasional pain on the journey, I think we all need to accept that these changes are for the better and the resulting position should be better overall.

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.

  • In this article:
    • Reactive vs. non-reactive property panes
    • Structuring web part properties into pages and groups
    • Textbox, Dropdown and Checkbox controls
  • Other articles:

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 get propertyPaneSettings() 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,
  IPropertyPaneSettings,
  IWebPartContext,
  PropertyPaneTextField
} from '@microsoft/sp-client-preview'

..to..

import {
  BaseClientSideWebPart,
  IPropertyPaneSettings,
  IWebPartContext,
  PropertyPaneTextField,
  PropertyPaneCheckbox,
  PropertyPaneChoiceGroup,
  PropertyPaneDropdown,
  PropertyPaneSlider,
  PropertyPaneButton,
  PropertyPaneToggle
} from '@microsoft/sp-client-preview'

From there, we can start expanding the code in the propertyPaneSettings() 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.
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  
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, and it’s there that I discovered this solution. Thanks Vard!

Checkbox (PropertyPaneCheckbox)
Properties:

Property

Description

text Text displayed next to the checkbox.
isChecked Specifies if the control is checked.
isEnabled Specifies if the control is enabled.
Code:
PropertyPaneCheckbox('checkboxProperty', {
                  text: 'This is the text',
                  isChecked: true,
                  isEnabled: true
                })
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. Apparently a get/set property, but I only saw it working for a get – however, you can set the selected item on the individual ‘option’ element which should be selected.
isDisabled 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',
                  isDisabled: false,
                  options: [
                    { key: 'Red', text: 'Red' },
                    { key: 'Green', text: 'Green' },
                    { key: 'DarkBlue', text: 'Dark blue', isSelected: true }
                  ]
                })
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.

Next time, we’ll continue our tour of the out-of-the-box web part property controls.