Upgrading to Angular 2 RC1 from beta – lessons learned
I recently upgraded my ng2 play repo from beta 15 to rc1 and I ran into a couple of things I thought would be nice to share since I’ve been getting quite a few mails about it.
angular2 -> @angular
To begin with all of the packages are now distributed under the @angular npm scope. This changes how Angular is installed via npm and how you import the code.
npm install --save @angular/core @angular/compiler @angular/common @angular/platform-browser @angular/platform-browser-dynamic rxjs@5.0.0-beta.6 zone.js@0.6.12
To import various symbols we needed to make the following adjustments:
- angular2/core -> @angular/core
- angular2/compiler -> @angular/compiler
- angular2/common -> @angular/common
- angular2/platform/browser -> @angular/platform-browser
- angular2/platform/server -> @angular/platform-server
- angular2/http -> @angular/http
- new package: @angular/router replaces angular2/router with breaking changes
Loading with SystemJS
Instead of configuring and mapping libraries and modules in index.html we load the app a bit differently, see systemjs.config.js for details.
RxJS Deps
What isn’t mentioned in the angular2 changelog is that the RxJS version it uses has a new dependency to symbol-observable, make sure to install it.
npm install --save symbol-observable
and map it up in systemjs.config.js.
New Router (breaking changes)
In app.ts a couple of imports have moved, we now import LocationStrategy, HashLocationStrategy and Location from common instead of router:
import {LocationStrategy, HashLocationStrategy, Location} from 'angular2/router'; import {ROUTER_PROVIDERS, RouterOutlet, RouteConfig, RouterLink} from 'angular2/router';
became:
import {LocationStrategy, HashLocationStrategy, Location} from '@angular/common'; import {ROUTER_PROVIDERS, ROUTER_DIRECTIVES, Routes, Router} from '@angular/router';
and we only pass ROUTER_DIRECTIVES to the components directive instead of RouterOutlet and RouterLink. Furthermore, we configure our routes with the Routes-attribute instead of RouteConfig and there is no ‘as’ property, meaning:
@RouteConfig([ { path: '/', component: Todo, as: 'Home' }, { path: '/about/:id', component: About, as: 'About' }, { path: '/profile', component: Profile, as: 'Profile' } ])
became:
@Routes([ { path: '/', component: Todo }, { path: '/about/:id', component: About }, { path: '/profile', component: Profile } ])
Router Parameters and no CanActivate
Here we have quite a few changes if we take a look in about.ts instead of resolving the params in the constructor from the RouteParams class we now need to implement OnActivate and get it in the routerOnActivate-method.
import { Router, RouteSegment, OnActivate } from '@angular/router'; ... export class About implements OnActivate { ... routerOnActivate(current: RouteSegment) { this.id = current.getParam('id'); } }
and in the view we now pass parameters using the routerLink like this:
About
instead of the previous syntax which was a bit more cumbersome imho:
About
We could previously prevent the component from loading with the CanActiviate-attribute, but there is no equivalent for that yet, see profile.ts.
For more changes see the breaking changes docs.
Cannot find name ‘Promise’
If you’re targeting ES5 and want to prevent errors such as:
- Cannot find name ‘Promise’
- Cannot find name ‘Map’
- Cannot find name ‘Set’
You’ll need to reference es6-shim at the top of your main typescript file, the file that boots the app if you will, in my case it’s boot.ts. (syntax highlighter messes up the brackets below)
///
To be able to do so you’ll need to run the following commands:
npm install -g typings typings install es6-shim --ambient
before you can reference the es6-shim typescript definition file.
Final words
Cool, that was a lot of changes, let’s see if they keep down the breaking changes from now on at least. I can’t shake the feeling that a lot of people feel that things are a lot more complicated now. I haven’t been able to answer all the emails, I’ve been busy with some new cool customer projects.
Upgrading material2 from alpha1 to alpha4 was seamless, I also cleaned up the loading in systemjs.config.js. Anyways make sure to star my ng2 play repo.
Until next time, have a nice day!
After updating it appears that the RouterOutlet class has been folded into ROUTER_DIRECTIVES, which breaks our custom RouterOutlet implementation to redirect to Login if a user is no longer authenticated. Is there a new method for determining whether a user is authenticated and redirecting them, or is there an alternative method for extending the RouterOutlet class?
Any luck with this? I just reached the same point
You don’t have to pass in the predefined ROUTER_DIRECTIVES array when configuring your app/component, if you want to use your own extended RouterOutlet you can simply just do what ROUTER_DIRECTIVES does (by checking the source what’s actually passed in) and bind up your own custom RouterOutlet instead. ROUTER_DIRECTIVES is just a helper so you don’t have to do all the boilerplate bootstrapping yourself, but in your case, it’s necessary to customize it. Makes sense?