2

I tried to follow this answer to make my Auth Service a singleton. Angular Service is reset on each call of it.

When a user logs in, i set a isLoggedIn variable in my AuthService, hoping to maintain this state. However when i navgiate to a restricted route such as /main. The variable is returning back false in my console when the user is infact logged in.

What am i doing wrong here?

auth.service.ts

import { JwtService } from './jwt.service';
import { Injectable } from '@angular/core';
import { ApiService } from './api.service';
import { UserService } from './user.service';

@Injectable()
export class AuthService {

  user: any;
  isLoggedIn: boolean = false;

  constructor(
    private apiService: ApiService,
    private jwtService: JwtService,
    private userService: UserService) {
  }

  login(credentials) {

    let endpoint = 'auth/'

    return this.apiService.post(endpoint, credentials)
      .map(res => {
        this.jwtService.saveToken(res.data.jwtToken);
        window.localStorage.setItem('user_id', res.data.user._id);
        this.user = res.data;
        this.isLoggedIn = true;
      });
  }

  logout() {

  }

  isAuthenticated(): boolean {return this.isLoggedIn};

}

auth.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthGuard implements CanActivate {


  constructor(private authService: AuthService, private router: Router) { }


  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {


    console.log(this.authService.isAuthenticated());
    if (this.authService.isAuthenticated()) {
      return true;
    }


    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
    return false

  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {HttpClientModule} from '@angular/common/http';

import { AppComponent } from './app.component';

import {BrowserAnimationsModule} from '@angular/platform-browser/animations';

import {FormsModule, ReactiveFormsModule} from '@angular/forms';


import {AppRoutingModule} from './app-routing.module';

import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component'
import { RegisterComponent } from './components/register/register.component';
import { LoginComponent } from './components/login/login.component';
import { MainComponent } from './components/main/main.component';


import {ApiService} from './services/api.service';
import {JwtService} from './services/jwt.service';
import {UserService} from './services/user.service';
import {SharedModule} from './shared/shared.module';



@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    RegisterComponent,
    LoginComponent,

  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    AppRoutingModule,
    SharedModule.forRoot(),
  ],
  providers: [
    ApiService,
    JwtService,
    UserService,
  ],
  bootstrap: [AppComponent]
})

export class AppModule { }

shared.module.ts

import {ModuleWithProviders, NgModule} from '@angular/core';
import {MaterialModule} from './material.module';
import { FlexLayoutModule } from "@angular/flex-layout";

import {AuthGuard} from '../guards/auth.guard';
import { AuthService } from '../services/auth.service';

@NgModule({
  imports: [
    MaterialModule,
    FlexLayoutModule,
    
  ],
  exports: [
    MaterialModule,
    FlexLayoutModule,    
  ]
})

export class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [
        AuthService,
        AuthGuard,
      ]
    };
  }
}

main.module.ts (restricted by auth.guard, for logged in users only)

import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';

import {MainComponent} from './main.component'
import {ChatComponent} from '../chat/chat.component';
import {MomentsComponent} from '../moments/moments.component';
import {SettingsComponent} from '../settings/settings.component';
import {QuestionsComponent} from '../questions/questions.component';
import { SearchComponent } from '../search/search.component';
import { FormsModule } from '@angular/forms';

import {SharedModule} from '../../shared/shared.module';


import { MainRoutingModule }       from './main-routing.module';

@NgModule({
  imports: [
    CommonModule,
    MainRoutingModule,
    SharedModule,
    FormsModule,
    
  ],
  declarations: [
    MainComponent,
    ChatComponent,
    MomentsComponent,
    SearchComponent,
    SettingsComponent, 
    QuestionsComponent,
  ]
})
export class MainModule {}
C.Champagne
  • 5,381
  • 2
  • 23
  • 35
Kay
  • 17,906
  • 63
  • 162
  • 270

1 Answers1

1

Since the page is refreshed , even though angular service is singleton, the values will be lost on page refresh.

Alternatively, you could just change the route without refreshing the page. Or you could store the LoginStatus on localstorage variable and get information on other pages if you really want the page refresh to happen

this.isLoggedIn = true;
localStorage.setItem('isLoggedIn', 'true');
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
  • Im having trouble then deciding what the best method is to get the authenticated user. if you see this question https://stackoverflow.com/questions/46631207/angular-4-node-how-to-check-for-authenticated-user-using-auth-guard i'm not able to call the backend service in time to check if the user is authenticated – Kay Oct 08 '17 at 17:28
  • Provide services(auth/guard) in the app.module Instead of shared module – Abhishek Singh Oct 08 '17 at 17:32
  • @KHAN if you are dealing with token , you dont have to make another call to check if user is authenticated. i have answered the question – Sajeetharan Oct 08 '17 at 17:35