Author Archives: Cameron Dwyer

Vote for our app in the Office 365 Hack Productivity competition!



Microsoft is currently running a Hack Productivity competition for creating apps that leverage Office 365 Add-ins and/or APIs to deliver an app that increases user productivity.

I’ve been working with the awesome dev team at OnePlace Solutions to cook up a modern Outlook Add-in that will run on any device and allow a user to quickly and easily save email and/or attachments from Outlook to SharePoint/Office 365 Groups.

We think it’s an awesome productivity app as it makes use of the “dead-time” you get during the day when you haven’t got time to do any heavy work but have your phone or tablet handy. This allows you to do those tasks like filing emails into your Project Management System in SharePoint while catching the train to work, or saving that updated document you’ve been sent into your Legal Matter Management System in SharePoint while waiting for your doctor’s appointment.

We are using all the cool technologies to make the magic happen. Running as a super fast Angular 2 Outlook Add-in and looking very slick thanks to the Office UI Fabric! We are utilizing the Microsoft Graph, SharePoint and Exchange services of Office 365 and hosting the app 100% on Microsoft’s Azure Cloud.

We didn’t just cobble together an app for the Hackathon, we built this app to be ready for the prime time and it will become a commercial product offering in the very near future. We have released the app into the Office Store as a preview where you can take a look at what we’ve built and try it out for yourself.

Please take a look and vote for our submission to the Hackathon

Get the OnePlaceMail for SharePoint Online preview app from the Office Store today.


OnePlaceMail for SharePoint Online – screenshot 1OnePlaceMail for SharePoint Online – screenshot 2OnePlaceMail for SharePoint Online – screenshot 3


Learn more about the app by visiting the OnePlace Solutions website


Bug in Outlook add-in commands showing command label instead of the add-in title on first use in a session

It seems there is a bug with the Outlook add-in commands when using the add-in from Outlook Web Access.

When using the add-in command (ribbon button) to open a task pane to show your add-in the label of the command button is shown at the top of the add-in where the add-in title should be. If you close the add-in and use the command button subsequent times in a session, then the add-ins title is correctly displayed.

Refreshing the browser window and again trying to use the add-in with show the command button label again (but just the first time the add-in is used).

I have been able to reproduce this issue with the Command Demo add-in from the Office Dev site:

1. Clone from GitHub

2. Run locally using gulp serve-static (as per instructions in the GitHub repo)

3. Deploy the add-in manifest (as per instructions in the GitHub repo)

On first use of the add-in in a session (or after refreshing the browser window) the add-in title uses the label of the command button. In the case below the button label of “Display all properties” is shown.


If you close the add-in and then click on the same command button subsequent times then the correct add-in title of “Add-in Command Demo” is displayed.


This bug only seems to affect OWA, Desktop Outlook 2016 consistently displays the correct add-in title as shown below.


It would also be nice if the header we displayed in Desktop Outlook was consistent with OWA. As you can see from the screenshots above OWA shows the add-in icon in the header whereas Desktop Outlook just has the title without an icon.

I’ve logged this bug on UserVoice, if it’s causing pain for you please vote it up!

Issues launching Outlook add-ins directly to a SPA route using fragment URLs

Modern Single Page Applications (SPAs) run in the browser as a single HTML page and use JavaScript to dynamically load content and provide the functionality of the application without having to reload the entire browser window as the user is interacting with the application. To support navigating SPAs, a commonly used technique is to perform navigation (or routing as it is called in the Angular world) based on URL fragments.

The basic premise of how this works is that the URL that you see in the browser window always refers to the same HTML page hosting your SPA e.g. http://myserver/spa-app/index.html

As the user navigates around the application this is done using URL fragments (the bit after the #) e.g. http://myserver/spa-app/index.html#configurationpage or http://myserver/spa-app/index.html#customerspage

This allows the browser to not go back to the server to request a page refresh (because we are always on the same page http://myserver/spa-app/index.html) but the SPA can react to the change of URL by reading the Fragment of the URL and route the user to the correct area of the app. The browser history also keeps track of the Fragment URL so this can provide a nice navigation experience.

That was a very basic explanation and I suggest reading this good primer on Fragment URLs (or hashbangs as they are sometimes referred).

So this leads us to Outlook add-ins and the problem I’ve encountered. Lets illustrate this with an example so that the use case becomes clear.

Imagine we have a simple SPA that shows a To Do list. The main screen of the app (http://myserver/spa-app/index.html) just shows the To Do list. There is also a second screen in the app for creating new To Do items(http://myserver/spa-app/index.html#newitem).

In the Outlook add-in manifest you provide a URL to your page that Outlook will load up in response to the user activating your app. The Microsoft preferred way of triggering this in Outlook is via Commands that appear as buttons in the Outlook Ribbon (in the desktop version of Outlook). If we create such a Ribbon button and specify the URL of the main screen of the app (http://myserver/spa-app/index.html) everything works just fine. Within the app itself, it can navigate off to http://myserver/spa-app/index.html#newitem to show the screen to create a new item. But what if we want to provide Outlook Ribbon buttons that streamline the process and let the user go straight to creating a new to do item rather than first having to open the app, then navigate within the app to create the item? Having the main functions of you app accessible as Ribbon buttons in Outlook is a huge time saver for users.

So what happens when we try to use the new item URL Fragment behind a Ribbon button?

If we specify a URL of http://myserver/spa-app/index.html#newitem in the add-in manifest, the following is the URL that Outlook actually launches the add-in with:



Obviously this is going to wreak havoc with your SPA. The original URL Fragment #newitem looks to be encoded in the resulting URL as “&_serializer_version=1newitem” although how to reliably detect and extract this and then do the correct routing within your SPA is challenging!

European SharePoint Conference (Vienna, November 14-17)

eurpoean-sharepoint-conferece-cameron-dwyerI’m excited to have to opportunity to attend the European SharePoint Conference this week (November 14-17) in Vienna. Since the amalgamation of the Microsoft SharePoint Conference into the Microsoft Ignite Conference the last 2 years, I’m really looking forward to a dedicated SharePoint conference again. The SharePoint community has always been such a bright, vocal and welcoming community and this is the first time I’ve travelled to Europe for the event.

Over the last 3 years we’ve seen Microsoft focus heavily on marketing Office 365 and the different services it offers. SharePoint had been relegated to the background and we heard little about it, even though it was the central to many of the Office 365 services. With Jeff Teper back on the team I get a sense that SharePoint is now back in the spotlight and the rate of innovation and change in SharePoint is at a level that we haven’t seen for years.

It’s an exciting new world for SharePoint and I’m keen to talk to those attending the conference to see how the cloud and Office 365 is being adopted through Europe.

Personally I have spent a lot of time recently on non-Microsoft technologies as we look to create the products of the future that will be running under non-Microsoft web technology stacks and across all devices.

While we will be showing our industry leading OnePlace Solutions product suite (OnePlaceMail, OnePlaceDocs, OnePlaceLive) at the conference we will also be demonstrating some of the cutting edge work we are doing such as the cross device OnePlaceConnect Outlook add-in that I’d imagine is the first commercial product in the Office 365 space written in Angular 2 and utilizing the ahead-of-time compiler for a blazingly fast user experience.

I’m really looking forward to having some great conversations and meeting new people as well as some of our existing customers and partners.

we-love-sharepoint - CopyOnePlace Solutions is a Gold Sponsor of the event and I’ll be on the booth during the breaks throughout the conference, so if you are attending and have the opportunity then please come up to the OnePlace Solutions booth and say hi. We will also be giving away some swag and prizes so come and grab some of those as well!

How to avoid errors installing npm packages globally in Visual Studio Code

I like to use the Integrated Terminal Window inside Visual Studio Code, just because it’s there and it runs commands scoped to the project directory I’m in. I find it faster and more convenient than opening up another command windows or nodejs command window and then having to set the current directory to my project folder.

A common issue I hit is when installing npm packages globally; I get errors trying to do it from the Integrated Terminal Window.


Take the following npm command that tries to install the bower package globally:

npm install -g bower




Running the command throws the following error:

npm ERR! Error: EPERM: operation not permitted, mkdir 'C:\Program Files (x86)\nodejs\node_modules\.staging'

npm ERR! at Error (native)

npm ERR! { [Error: EPERM: operation not permitted, mkdir 'C:\Program Files (x86)\nodejs\node_modules\.staging']

npm ERR! errno: -4048,

npm ERR! code: 'EPERM',

npm ERR! syscall: 'mkdir',

npm ERR! path: 'C:\\Program Files (x86)\\nodejs\\node_modules\\.staging' }

This is because when you install npm packages globally they go into the nodesjs\node_modules directory in program files (rather than in the project folder where you are writing your code). Writing to folders under Program Files requires elevated privileges . To get around this using the Integrated Terminal window in Visual Studio Code just make sure when you start Visual Studio Code that you run as an Administrator.



Further Reading


Microsoft Ignite 2016 – Ready, Set, Connect

we-love-sharepoint - CopyOnePlace Solutions is proud to be an exhibitor and sponsor again this year at the Microsoft Ignite conference in Atlanta. Ignite is Microsoft’s premier conference this year for Office 365, SharePoint, Exchange, Azure, Windows and related technologies.

I’ll be on the OnePlace Solution booth (#563) during the conference talking about our suite of products that bring SharePoint and Office 365 to where you work such as Outlook, Word, Excel, PowerPoint, Adobe Acrobat, and Windows Desktop.

CROSS_PLATFOMI’m very excited to be unveiling our latest product OnePlaceConnect at the conference. OnePlaceConnect is focused on bringing cloud based solutions such as Office 365 and SharePoint directly into the applications you use, on whatever device you use them (yes that means on your iPad/Android tablets, phones, Mac and of course your Windows devices).


Registration is now open to participate in the OnePlaceConnect Preview and be one of the first to get your hands on the new product.


The following are some really useful resources that I often refer people to at conferences.

OnePlaceMail – Intro video

OnePlaceDocs – Intro video

OnePlaceLive – Scenarios Unleashed (Project Management, Legal Matter Management)

OnePlaceLive – Email Tracking video


It’s always fun meeting new people at conferences and hearing of successes, challenges and battle wounds you’ve had with technology. It’s also awesome to catch up with existing customers and partners while I’m in the US as well, so please drop by the OnePlace Solutions booth if you get a chance.

We will have some swag at the booth, and we have new and improved hacky sacks/footbags/juggling balls to give away this conference. I’m more excited than I probably should be about those!

microsoft-band2We will also be giving away a Microsoft Band 2, so make sure you drop by for your chance to win.

Have a great conference and hope to see you at the booth or one of the many events.


Reach out to me @CameronDwyer on Twitter during the conference.




Upgrading from Angular 2 RC5 to RC7 – watch out for required NPM version

I skipped RC6 and made the jump straight from RC5 to RC7.

First step was to upgrade the versions of my dependencies (both the “dependencies” and “devDependencies”) in the package.json file. To get the magic recipe of what versions of each dependency were needed I referred back to the QuickStart guide on the website.

"name": "myapp",
"version": "1.0.0",
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings"
"license": "ISC",
"dependencies": {
"@angular/common": "2.0.0-rc.7",
"@angular/compiler": "2.0.0-rc.7",
"@angular/compiler-cli": "0.6.1",
"@angular/core": "2.0.0-rc.7",
"@angular/forms": "2.0.0-rc.7",
"@angular/http": "2.0.0-rc.7",
"@angular/platform-browser": "2.0.0-rc.7",
"@angular/platform-browser-dynamic": "2.0.0-rc.7",
"@angular/router": "3.0.0-rc.3",
"@angular/upgrade": "2.0.0-rc.7",
"systemjs": "0.19.27",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12",
"zone.js": "^0.6.21",
"angular2-in-memory-web-api": "0.0.19",
"bootstrap": "^3.3.6"
"devDependencies": {
"concurrently": "^2.2.0",
"gulp": "3.9.1",
"lite-server": "^2.2.2",
"typescript": "^1.8.10",
"typings": "^1.3.2"

Running npm install with the upgraded dependencies was failing for me with the following error:

npm ERR! argv "c:\\Program Files (x86)\\nodejs\\node.exe" "c:\\Program Files (x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
npm ERR! node v4.4.3
npm ERR! npm v2.15.1
npm ERR! peerinvalid The package typescript@1.8.10 does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer @angular/compiler-cli@0.6.1 wants typescript@^2.0.2
npm ERR! Please include the following file with any support request:
npm ERR! C:\Projects\….\npm-debug.log

From the documentation it states than you must have node 4.x.x or higher, and npm 3.x.x or higher.

You can see from the error message above that I have node v4.4.3 (good) and npm v2.15.1 (bad).

So my fix was to upgrade npm to at least v3. I followed this information in this thread to upgrade npm to the latest available version by:

Opening cmd.exe as administrator
Navigating to C:\Program Files (x86)\nodejs
Running this command: npm install npm@latest

Running an npm install on the project now works after upgrading npm to v3.10.7. I now a warnings relating to some peer dependencies instead of the failures.

npm WARN optional Skipping failed optional dependency /lite-server/browser-sync/chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.14
npm WARN optional Skipping failed optional dependency /karma/chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.14
npm WARN @angular/compiler-cli@0.6.1 requires a peer of typescript@^2.0.2 but none was installed.

How to access properties of Office.js objects that don’t exist in the Typescript definition file

When developing Office Add-ins and using Typescript, I’ve found the Office.js Typescript definition file available at DefinatelyTyped to only support a fraction of the objects and properties that are available within the Office.js library.

To give you an idea of what I mean, here is a list of properties that are available on the Office.context.mailbox.item object (according to the API documentation in the Outlook Dev Center)



And here are all the properties of that same object using the Typescript definition file:


I was left wondering where the rest of the properties were. They simply don’t exist in the Typescript definition file. So this leaves us in a bit of a bind, because we are using Typescript we can’t just reference a property that doesn’t exist in the Typescript definition file (even though we know the property will exist at run-time). The Typescript compiler will do it’s job well and throw up a compile time error that the property does not exist.

Without going to the effort of taking the Office.js Typescript definition file and extending it yourself to start filling it out you may want to consider the following work around.

We can declare an object in Typescript without a specific type by specifying it’s type as any. If we do this to an object within the Office.js library we can get an un-typed handle to the object. As the object in now un-typed, we can call any property of that object we like (whether it exists or not). Below is the code that will give us access to the subject of the email that is not available in the Typescript definition file.


If the property exists at runtime then great, if not then we will get a run-time error. It is definitely a step backwards and is why we use Typescript in the first place!

It would get a bit unwieldy if you used this technique throughout your code, and I’d like to think that as we get updated Office.js Typescript definition files that we can remove this type of code from our project and access the properties in a properly typed way. To isolate your use of this technique to a central location and facilitate removing the code later on, I’d suggest creating a class that takes in the object (e.g. Office.context.mailbox.item) then inside the class it gets the un-typed handle to the item and provides methods or properties that return the missing properties (with the bonus that the values returned can have a type associated with them). Below is an example of a class with static methods that provide typed access to missing properties on a mailbox item.


Hopefully the Office team will see the value in publishing current and complete Typescript definition files so we don’t have to write code like this in future.

Fingers crossed.

Day zero resources for upgrading from Angular 2 RC4 to RC5

Angular 2 RC5 is now available!

For those looking to get their hands dirty from day 1, I’ve compiled some links of resources that are already available that helped me along the way.


What’s New


The biggest change is the new NgModule which will impact the bootstrapping of your application and the way components reference directives and pipes.


RC5 Changelog


Ahead of Time (AoT) Compiler

A more detailed look at the offline (AoT) compiler, lazy loading and other changes in RC5


How to Upgrade

RC4 to RC5 Migration steps


Update Dependencies

A quick way to update your dependencies from RC4 to RC5 is to take a look at the sites’ Quick Start project which has already been updated to use RC5. Change your to be the same, run npm install and you are away.



Follow the Examples

All of the Plunker examples from website documentation seem to have been updated to use RC5 and show the new patterns and serve as good examples of how you should be doing things the RC5 way. For example, there have been some changes in routing which can be seen in this Plunker:

Getting the Angular 2 Router Working for an Office Addin


I have simple Angular 2 Office Addin and attempting to use the Angular 2 Router to route between two components. My two components are called ViewOne and ViewTwo.

Here’s what the UI for the Office Addin looks like:


When the using the Router to navigate, the following errors related to the this._history.pushState function are thrown to the JavaScript console


The error message text is:

EXCEPTION: Error: Uncaught (in promise): TypeError: this_history.pushState is not a function

The same page displays without any error if it is not running as an Office Addin (rather if I just run the same router code on a standalone web page).

My best guess is that this error is due to the Office Addin framework and the fact that the Angular 2 app is running inside a sandbox iframe. I have tried running the same Angular app in a sandbox iframe on an otherwise generic html page however and I can’t reproduce the error so I think it is unique to something within the Office Addin framework.

This particular error has to do with the Angular 2 app trying to push the URL change to the web browsers history (to support back/forward navigation). In an Office Addin this doesn’t really make much sense as the Addin isn’t in control of the whole page so we wouldn’t want the Addin taking over the browsers URL history anyway.

In order to stop the Angular 2 router trying to make this call to the browser you can use a custom location strategy. In my case I was already using the HashLocationStrategy (rather than the default HTML5 routing strategy).

I went to the Angular 2 GitHub repo and found the source code for the HashLocationStrategy and created a new class in my Angular 2 app called CustomHashLocationStrategy. I just dumped all the source code into the new file, changed the name of the class and removed the two lines of code that try to update the web browsers history as shown below.


Now when bootstrapping my Angular 2 app I use my new CustomHashLocationStrategy instead of the HashLocationStrategy. Here’s what that change looks like in code.

Before (click for full size image):


After (click for full size image):


After this change I can now navigate between the 2 routes without any errors being thrown to the console.


The code shown in this article in the Angular 2 Router in RC1. I also had the same issue using the “Router-Deprecated” in RC1, the same solutions worked for me using the deprecated router.

I also tested that this fix worked across Chrome, IE, Edge and Windows Desktop Office Client.


Further reading:

%d bloggers like this: