2

I have two components.LoginComponent and LandingComponent.I have to route from login page to landingpage after validating username and password. But I can't access router inside the service which was a global/page variable. It shows an error "TypeError: Cannot read property 'router' ".

import {Component} from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, Router } from 'angular2/router';
import {LoginService} from './login.service';
import {NgForm} from 'angular2/common';

@Component({
    selector: 'login',
    templateUrl: './app/app-components/login/login.html',
    styleUrls:['./app/app-components/login/login.css'],
    directives: [ROUTER_DIRECTIVES],
    providers:[LoginService]
})
export class LoginComponent {

  //DECLARATIONS
  login={username:"",password:""} ;
  active = true;
  submitted = false;  
  router:Router;

  constructor(private _loginService: LoginService,private _router: Router) {
    this.router = _router;
   }

  onAuthenticate() {
      this.submitted = true;
      this._loginService.Login().then( function (loginValues) {        
          if(loginValues.username=="sampleuser" && loginValues.password=="a"){
            this.router.navigate(['LandingPage']);
          }
          else{
           alert("Invalid Username or Password!!");
          }
      });      
   }  
} 

LoginService

import {Injectable} from 'angular2/core';

@Injectable()
export class LoginService {
    Login(){
    return Promise.resolve(login);
    }
}

var login={
    username:"sampleuser",
    password:"a"
}
sainu
  • 2,686
  • 3
  • 22
  • 41
  • Where is your route config? Perhaps you just missed to add it, because the decorator is imported in your LoginComponent – Dinistro May 02 '16 at 05:45

4 Answers4

3

You can only inject the router in components that have routes.

You might need to provide LoginService only on the root component (or alternatively bootstrap(...)) to get a shared instance.

You can inject Router to your LoginService.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
2

I see that you define the service into the providers of the login component:

@Component({
  selector: 'login',
  templateUrl: './app/app-components/login/login.html',
  styleUrls:['./app/app-components/login/login.css'],
  directives: [ROUTER_DIRECTIVES],
  providers:[LoginService] // <-------
})
export class LoginComponent {
  (...)
}

If the landing component is a sub component, it will share the same instance otherwise no.

To be able to share the same instance, you need to specify the service when bootstrapping your application:

bootstrap(AppComponent, [LoginService]);

And remove the service from providers of the login service:

@Component({
  selector: 'login',
  templateUrl: './app/app-components/login/login.html',
  styleUrls:['./app/app-components/login/login.css'],
  directives: [ROUTER_DIRECTIVES],
})
export class LoginComponent {
  (...)
}

It's the way hierarchical injectors work in Angular2. For more details, you could have a look at this question:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
2

this.router = _router in your constructor is wrong

private _router in your constructor create an instance variable in your class. So for you to access it you must prepend this. to your variable _router in your constructor.

change it to

this.router = this._router;

so the constructor will finally be like so

constructor(private _loginService: LoginService,private _router: Router) {
   this.router = this._router;
}
oseintow
  • 7,221
  • 3
  • 26
  • 31
2

You should use the arrow-functions like this in your LoginComponent:

this._loginService.Login().then( (loginValues) => {
    if(loginValues.username=="sampleuser" && loginValues.password=="a"){
        this.router.navigate(['LandingPage']);
    }
    else{
        alert("Invalid Username or Password!!");
    }
}); 

This will not change the this inside the function. Otherwise, the this does not point to the instance of you LoginComponent and your router can not be found.

Dinistro
  • 5,701
  • 1
  • 30
  • 38
  • but my error changed to: "Uncaught (in promise): Component "LoginComponent" has no route config." – sainu May 02 '16 at 05:33
  • @sainu Where do you bootstrap your application? And where do you have your route-config? Take a look at the answer from Günther Zöchbauer. – Dinistro May 02 '16 at 05:35