1
votes

In Angular2 how can i get GET params and store it locally like in a session in Php ?

http://localhost:8080/contextPath/index.html?login=true#token_type=Bearer&expires_in=9999&access_token=xxxXXXXXxxx

I Need to get the access_token before continue the nav to the dashBoard component which is calling a secure Rest Webservice. ( wich need the token )

@Component({
 selector: 'my-app',
 template: `
 <h1>{{title}}</h1>
  <nav>
    <a [routerLink]="['Dashboard']">Dashboard</a>
    <a [routerLink]="['Heroes']">Heroes</a>
  </nav>
  <router-outlet></router-outlet>
  `,
    directives: [ROUTER_DIRECTIVES],
    providers: [
        ROUTER_PROVIDERS,
        HTTP_PROVIDERS,
        HeroService,
        RouteParams
    ]
})
@RouteConfig([
    {
        path: '/heroes',
        name: 'Heroes',
        component: HeroesComponent
    },
    {
        path: '/dashboard',
        name: 'Dashboard',
        component: DashboardComponent,
        useAsDefault: true
    },
    {
        path: '/getHero/:id',
        name: 'HeroDetail',
        component: HeroDetailComponent
    },
])
export class AppComponent {
    title = 'Tour of Heroes';
    private token2;

    constructor(
        private _routeParams:RouteParams) {

        this.token2 = _routeParams.get('access_token');
        console.log("token from Url : "+ this.token2);
    }
}

Actually i get an "EXCEPTION: Cannot resolve all parameters for 'RouteParams'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'RouteParams' is decorated with Injectable" after the launch of this app.

hero.service.ts :

@Injectable()
export class HeroService {
    ot: Observable<string>;
private token2 =  'test';

private serviceUrl = 'http://localhost:8080/Context_Path/';
private token = "xXXXX";
private headers = new Headers();

constructor(private http:Http){
    this.headers.append('Authorization', 'bearer '+ this.token);
    this.headers.append('Content-Type', 'application/json');
}
//Renvois maintenant un observable sur lequel un composant doit s'incrire
getHeroes() {

    var opUrl = 'getHeroes.json';
    //appel asynchrone comme pour un serveur http
    //return Promise.resolve(HEROES);
    //return HEROES;
    //Recuperation des heros façon rest via fed
    return this.http.get(this.serviceUrl + opUrl,{
            headers: this.headers
        })
        //mise en relation du json retourné et d'un tableau de hero
        .map(res => <Hero[]> res.json())
        //TODO[PROD] commenter avant la mise en prod
        .do(data => console.log(data)) // eyeball results in the console
        .catch(this.handleError);
}
getHero(id:number) {
    var opUrl = 'getHero.json?id='+id;
    return this.http.get(this.serviceUrl + opUrl,{
            headers: this.headers
        })
        //TODO[PROD] commenter avant la mise en prod
        .do(data => console.log(data)) // eyeball results in the console
        .catch(this.handleError);

}
private handleError (error: Response) {
    // in a real world app, we may send the error to some remote logging infrastructure
    // instead of just logging it to the console
    console.error(error);
    return Observable.throw(error.json().error || 'Server error');
}
//pour verifier le comportement d'un gros temps de réponse
getHeroesSlowly() {
    return new Promise<Hero[]>(resolve =>
        setTimeout(()=>resolve(HEROES), 2000) // 2 seconds
    );
}
}

Dashborad.component.ts :

import { Component, OnInit } from 'angular2/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';
import { Router } from 'angular2/router';

@Component({
    selector: 'my-dashboard',
    templateUrl: 'app/dashboard.component.html',
})
export class DashboardComponent implements OnInit {
    heroes: Hero[] = [];
    private errorMessage;

    constructor(
        private _router: Router,
        private _heroService: HeroService) {
    }

    ngOnInit() {
        this._heroService.getHeroes()
            .subscribe(heroes => this.heroes = heroes,
                error => this.errorMessage = <any>error);
    }
    gotoDetail(hero: Hero) {
        let link = ['HeroDetail', { id: hero.id }];
        this._router.navigate(link);
    }
}

EDIT : 1 Following sugestion i modified my main.ts to :

bootstrap(AppComponent);
bootstrap(AppComponent, [ROUTER_PROVIDERS,HTTP_PROVIDERS,RouteParams]);

And removed providers in the app.components.ts

But an Error is occuring :

Cannot resolve all parameters for 'RouteParams'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'RouteParams' is decorated with Injectable.
angular2-polyfills.js:322 Error: TypeError: Cannot read property 'getOptional' of undefined(…)ZoneDelegate.invoke @ angular2-polyfills.js:322Zone.run @ angular2-polyfills.js:218(anonymous function) @ angular2-polyfills.js:567ZoneDelegate.invokeTask @ angular2-polyfills.js:355Zone.runTask @ angular2-polyfills.js:254drainMicroTaskQueue @ angular2-polyfills.js:473ZoneTask.invoke @ angular2-polyfills.js:425
angular2.dev.js:23740 EXCEPTION: No provider for RouteParams! (AppComponent -> RouteParams)

Edit 2 : Inatention error, new main.ts : ( with only ONE bootstrap this time >< )

bootstrap(AppComponent, [ROUTER_PROVIDERS,HTTP_PROVIDERS,RouteParams]);

There is only this Error now :

Cannot resolve all parameters for 'RouteParams'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'RouteParams' is decorated with Injectable.
angular2-polyfills.js:322 Error: TypeError: Cannot read property 'getOptional' of undefined(…)
1
this.token2 = _routeParams.get('access_token'); This part :)Slater
Do you have these providers in bootstrap() as well or only on your root component ` , directives: [ROUTER_DIRECTIVES], providers: [ ROUTER_PROVIDERS, HTTP_PROVIDERS, HeroService, RouteParams ] })?Günter Zöchbauer
I have that : bootstrap(AppComponent, [HTTP_PROVIDERS]); in my main.ts But even with : bootstrap(AppComponent, [HTTP_PROVIDERS,ROUTER_PROVIDERS]); I have the same Error :/Slater
You don't actually have two bootstrap(AppComponent) lines like shown in your question? (Edit: 1), do you?Günter Zöchbauer

1 Answers

2
votes

Update for deprecated router

Add these providers in bootstrap() only or AppComponent only

bootstrap(AppComponent, [
    ROUTER_PROVIDERS,
    HTTP_PROVIDERS])

and remove them everywhere else. There is no need for providing the same providers multiple times if they should be shared with the whole application.

Also ensure RouteParams and ROUTER_PROVIDERS are imported from angular2/router. They are not exported by angular2/core.

See also my answer to How to get GET paramater in Angular2?

In the root component you can inject the router and subscribe to route events, then get the params from the router like

export class AppComponent {
  constructor(private router:Router) {
    router.subscribe(route => {
      console.debug(this.router.currentInstruction.component.params);
    });
  }
}

On components added by the router you can inject RouteParams like and access the values like

export class Other{
    constructor(private routeParams: RouteParams) {
    console.debug(this.routeParams);
    console.log(this.routeParams.get('filter_industry'));
    console.log(this.routeParams.get('filter_start_with'));
  }
}

Plunker example