I am facing an issue where a Behavior Subject does not update a subscriber upon the .next(value) call.
Being new to typescript, I believe I might be overlooking something small. The implementation seems correct based on what I have researched.
Although there were similar issues discussed on the site, none of the solutions provided were able to resolve my problem. An example of such a discussion can be found here
The RestService is only included in the app.module.ts providers array.
The Auth Guard File can be found in (services/auth-guard.service.ts)
authenticated = false;
...
ngOnInit(){
this.restService.isLoggedIn().subscribe({
next: result => {
this.authenticated = result;
}
});
}
...
canActivate(route: ActivatedRouteSnapshot): boolean{
console.log(this.authenticated);
if(!this.authenticated){
this.router.navigate(['login']);
}
return this.authenticated;
}
}
Sections of the rest service file (services/rest.service.ts)
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { RequestOptions } from '@angular/http';
import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
import { Observable, BehaviorSubject } from 'rxjs';
import { User } from 'src/app/Interfaces/user';
import { tap } from 'rxjs/operators';
...
authSubject = new BehaviorSubject(false);
...
public _setAuthSubject(value){
this.authSubject.next(value);
}
public isLoggedIn() {
return this.authSubject.asObservable();
}
In the canActivate method, a console log always shows that this.authenticated is false. However, upon adding another subscriber call and checking the other variable, it becomes evident that it is actually true and has been updated. Am I overlooking something causing authentication not to be updated?
Additional information includes my app.module.ts:
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
IonicStorageModule.forRoot()
],
providers: [
AuthGuardService,
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
SQLite,
SQLitePorter,
RestService,
],
bootstrap: [AppComponent]
})
Also, the routing that invokes the auth guard service (app-routing.module.ts)
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { AuthGuardService } from './services/auth-guard.service';
const routes: Routes = [
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule', canActivate: [AuthGuardService]},
{ path: 'login', loadChildren: './login/login.module#LoginPageModule' },
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule { }
Lastly, here is the function that sets the auth subject to true (login/login.page.ts)
constructor(
public menu: MenuController,
private restService: RestService,
private router: Router,
private storage: Storage
) { }
async login(form){
this.restService.login(form.value).subscribe({
next: response => {
console.log(response)
if(response.access_token){
this.storage.set("ACCESS_TOKEN", response.access_token);
this.restService._setToken(response.access_token);
this.restService._setAuthSubject(true);
}
this.router.navigateByUrl('');
},
error: err => {
console.log('ERROR!: ', err)
}
});
}