Reputation: 479
I am making an Angular2 application. I have a login service class that is provided at the application level and is used by login component and authentication guard service.
If my understanding of DI is correct, once the service is provided at an application level through providers metadata of AppModule the same instance of the service is provided to all the components, when injected and hence the change to the member of the service class by one component will be reflected on the other service or component class.
I have provided the login service class in application level but changing the service's member variable from one component is not being reflected in other component. My login component changes the loggedIn variable to true, but when i access it from the auth guard service it is still getting the false value.
Following are my code snippets:
AppModule
@NgModule({
imports: [
BrowserModule,
HttpModule,
ReactiveFormsModule,
MyModule
],
providers: [
AuthguardService,
LoginService
],
declarations: [
AppComponent,
],
exports: [
],
bootstrap: [AppComponent],
})
export class AppModule { }
AuthguardService
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { LoginService } from './mymodule/login';
@Injectable()
export class AuthguardService implements CanActivate {
constructor(
private service: LoginService,
private router: Router
) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean{
let url: string = state.url;
return this.checkLogin(url);
}
private checkLogin(url: string){
debugger;
if (this.service.isLoggedIn()) {
console.log(this.service.loggedIn);
return true;
} else {
console.log(this.service.loggedIn);
this.router.navigate(['/']);
return false;
}
}
}
LoginService
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Injectable()
export class LoginService {
loggedIn: boolean = false;
constructor(
http: Http
){}
login(username: string, password: string){
let header = new Headers({
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return this.http.post(
'http://localhost/api/login',
JSON.stringify({login:username,password:password}),
{headers: headers}).map((res: Response)=>{
this.loggedIn = true;
return res.json();
})
.catch(this.handleError);
}
logout(){
this.loggedIn = false;
}
isLoggedIn(){
if(this.loggedIn == true){
return true;
} else {
return false;
}
}
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
Can anyone tell me what i am doing wrong here. When i call the login service from the login component the login is done successfully and the loggedIn variable is set to true but when i try to redirect it to other route and the AuthguardService uses login service the value of loggedIn is false. I have checked all the module class if there are multiple providers of the login service but there is not.
Any help is appreciated.
Upvotes: 1
Views: 1387
Reputation: 479
It seems that the way i submitted the form was the problem. I had called the login()
method on the button click rather than the (ngSubmit)
so when i click the login button, first the click event would fire and then the submit event. And the submit event was reloading the whole application causing it to make a new instance of everything. Always use (ngSubmit)
event to submit the form.
Upvotes: 1
Reputation: 71
This may happen if you add your service in the providers array of any other component other than module.ts
Upvotes: 1