1

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(…)
Sangwin Gawande
  • 7,658
  • 8
  • 48
  • 66
Slater
  • 817
  • 2
  • 10
  • 16
  • this.token2 = _routeParams.get('access_token'); This part :) – Slater Mar 24 '16 at 09:43
  • 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 Mar 24 '16 at 09:45
  • 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 Mar 24 '16 at 09:47
  • Looks like https://github.com/angular/angular/issues/7652 (https://github.com/angular/angular/issues/5999) – Günter Zöchbauer Mar 24 '16 at 09:59
  • You don't actually have two `bootstrap(AppComponent)` lines like shown in your question? (Edit: 1), do you? – Günter Zöchbauer Mar 24 '16 at 10:01
  • Remove `RouteParams` from `providers` entirely, it is already included in `ROUTER_PROVIDERS`. `RouteParams` needs a factory and can't be provides just as type. – Günter Zöchbauer Mar 24 '16 at 10:08
  • I'm trying to look about the "factory" then. Do you have any example that I can study ? – Slater Mar 24 '16 at 10:20
  • Just remove `RouteParams` from the providers list. `RouteParams` is maintained by the router. If you register it with a factory, you might get rid of the error, but the injected instance won't have any route parameter values. – Günter Zöchbauer Mar 24 '16 at 10:22
  • Okey , no more error when i don't use RouteParams like that. But i don't have any idea on How i can get the "access_token=xxxXXXXXxxx" without that :/ In php I can do extract($_GET) but i don't find how to d othe same thing in angular ^^" – Slater Mar 24 '16 at 10:37
  • AFAIK RouteParams would provide what you defined as `:id` in your routes. It seems what you want is a query parameter, not a route parameter? – Günter Zöchbauer Mar 24 '16 at 10:40
  • Huuuuu Maybe, I'm trying to get the access token because an Oauth2 servire redirect after authentication on the index page of my page with the token passed in a Get : "access_token=xxxXXXXXxxx" and i need to get back that token to use it in the application. – Slater Mar 24 '16 at 10:46
  • http://stackoverflow.com/questions/34599174/how-to-handle-query-parameters-in-angular-2 indicates that you can get query parameters from `RouteParams` as well. Haven't tried myself yet. Looks like I was wrong about my last comment above. – Günter Zöchbauer Mar 24 '16 at 10:55
  • I got the same problem, what is your solution if you have one? http://stackoverflow.com/questions/36784822/how-to-get-get-paramater-in-angular2 – tom10271 Apr 22 '16 at 04:29
  • btw I think you don't need to provide it in `bootstrap` function, RouteParams is not injectable. @GünterZöchbauer am I right? – tom10271 Apr 22 '16 at 04:31
  • @aokaddaoc you are right, `RouteParams` shouldn't be provided, they are provided by the router. – Günter Zöchbauer Apr 22 '16 at 04:34

1 Answers1

2

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

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I did that. Same error, and the import {ROUTER_PROVIDERS, RouteParams} from "angular2/router"; is in the "main.ts" file – Slater Mar 24 '16 at 09:57