Category Archives: Angular 2

How to Avoid Chrome Security Issues Developing Office Add-in Hosted on localhost

When developing add-ins for Office you are often serving the add-in from a local web server on a URL using the host name “localhost”. Office add-ins also require the web server to use SSL to serve the resources for the add-in. The Chrome security implementation will fire off a security error under most common development scenarios. This is when the domain of the SSL certificate does not match “localhost”.

You will see this problem manifest itself by causing your add-in to not start and show an error stating:

“Add-in Error  Something went wrong and we couldn’t start this add-in. Please try again later or contact your system administrator”

cameron-dwyer-chrome-debug-localhost-00b-add-in-error-couldnt-start

If you have the Developer Tools window open in Chrome you will see error messages getting output with the text:

“net::ERR_INSECURE_RESPONSE”

cameron-dwyer-chrome-debug-localhost-00a-net-err-insecure-response

There is a relatively easy workaround to this problem that you can implement on your development machine to allow Chrome to bypass this certificate check on URLs served from “localhost”.

Type the following into the Chrome browser URL bar:

chrome://flags/#allow-insecure-localhost

Enable the option:

“Allow invalid certificates for resources loaded from localhost. Mac, Windows, Linux, Chrome OS, Android

Allows requests to localhost over HTTPS even when an invalid certificate is presented.”

cameron-dwyer-chrome-debug-localhost-01-allow-insecure-localhost

After making this change you will need to restart Chrome.

cameron-dwyer-chrome-debug-localhost-02-relaunch-now

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

image

 

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

http://www.oneplacesolutions.com/oneplacemail-for-office365-sharepoint-online.html

image

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:

http://myserver/spa-app/index.html?et=&_host_Info=Outlook|Web|1…_1480636166782|ocii1|https://outlook.office.com/owa/?realm=XYZ.com#&_serializer_version=1newitem&_xdm_Info=-133b2041_-3d735892_1480636166782|ocii1|https://outlook.office.com/owa/?realm=XYZ.com

 

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!

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

 

vscode-npm-01-integrated-terminal-window-cameron-dwyer

 

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.

vscode-npm-02-run-as-admin-cameron-dwyer

 

Further Reading

https://www.cnet.com/au/how-to/always-run-a-program-in-administrator-mode-in-windows-10/

http://windowsreport.com/make-files-apps-run-as-admin-windows-10/

http://winaero.com/blog/how-to-run-an-app-as-administrator-in-windows-10/

 

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 Angular.io 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! code EPEERINVALID
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 Angular.io documentation https://angular.io/docs/ts/latest/guide/npm-packages.html 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.

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

NgModule

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

https://angular.io/docs/ts/latest/guide/ngmodule.html

 

RC5 Changelog

https://github.com/angular/angular/blob/master/CHANGELOG.md#200-rc5-2016-08-09

 

Ahead of Time (AoT) Compiler

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

http://angularjs.blogspot.com.au/2016/08/angular-2-rc5-ngmodules-lazy-loading.html

 

How to Upgrade

RC4 to RC5 Migration steps

https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html

 

Update Dependencies

A quick way to update your dependencies from RC4 to RC5 is to take a look at the Angular.io 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.

https://angular.io/docs/ts/latest/quickstart.html

clip_image001

 

Follow the Examples

All of the Plunker examples from Angular.io 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:

https://angular.io/resources/live-examples/toh-5/ts/plnkr.html

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:

office-addin-angular2-router-pushState-cameron-dwyer-01-addin-ui

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

office-addin-angular2-router-pushState-cameron-dwyer-02-zone-js-error

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.

office-addin-angular2-router-pushState-cameron-dwyer-03-location-strategy

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):

office-addin-angular2-router-pushState-cameron-dwyer-04-bootstrap-before

After (click for full size image):

office-addin-angular2-router-pushState-cameron-dwyer-04b-bootstrap-after

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

office-addin-angular2-router-pushState-cameron-dwyer-05-addin-ui-working

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:

http://stackoverflow.com/questions/36182807/angular-2-routed-apps-hosted-in-iframes

https://www.illucit.com/blog/2016/05/angular2-release-candidate-1-rc1-changes/

https://angular.io/docs/ts/latest/guide/router.html

%d bloggers like this: