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