Reputation: 11
In Angular 17 running in Docker I've got standalone AppComponent that contains <router-outlet></router-outlet>
.
When I try to subscribe to any http request in app.component.ts, app doesn't rebuild and throws an error:
_Observable {
source: _Observable {
source: _Observable {
source: [_Observable],
operator: [Function (anonymous)]
},
operator: [Function (anonymous)]
},
operator: [Function (anonymous)]
}
ERROR ReferenceError: localStorage is not defined
how I try to subscribe to http request: this._authService.isAdmin().subscribe()
isAdmin() method in my service:
isAdmin(): Observable<any> {
return this._http.get(LARAVEL_URL + '/api/auth/isAdmin')
}
Anyway the same problem with any request. While this error persists localStorage in DevTools becomes empty.
I also have interceptor and AuthGuard that guards component at the route '/'.
Interceptor:
export const authInterceptor: HttpInterceptorFn = (
req: HttpRequest<any>,
next: HttpHandlerFn
): Observable<HttpEvent<any> | any> => {
const token = localStorage.getItem('auth_token');
if(token) {
const cloned = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
return next(cloned);
} else {
return next(req);
}
};
AuthGuard:
export class AuthGuard implements CanActivate {
constructor(
private authService: AuthService,
private router: Router
) {}
canActivate(): boolean {
if (this.authService.isAuthenticated()) {
return true;
} else {
this.router.navigate(['/auth']);
return false;
}
}
}
How my routes are guarded:
{ path: '', component: MainComponent, canActivate: [AuthGuard]},
How I provide my authInterceptor:
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptors([authInterceptor]), withFetch()),
],
};
I tried to perform http request in another component and import it to AppComponent but it still got the same error.
It's important to make request at app component becuase eventually I want to wrap routerOutlet with MatSideNav from material UI and make my whole app contain sideNavigation. In order to switch content of matSideNav I need http request.
Upvotes: 1
Views: 409
Reputation: 58199
On the server localStorage
is non existant, so we should check ifs the server and set a default value and avoid accessing the localStorage
! We can perform this check by using the below function and token! You could store the token in a service and access that directly instead of localstorage when on the server, so that the API calls do not fail!
export const authInterceptor: HttpInterceptorFn = (
req: HttpRequest<any>,
next: HttpHandlerFn
): Observable<HttpEvent<any> | any> => {
const platformId = inject(PLATFORM_ID);
const token = isPlatformBrowser(platformId) ? localStorage.getItem('auth_token') : 'some default auth token';
if(token) {
const cloned = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
return next(cloned);
} else {
return next(req);
}
};
Upvotes: 0