I need that canActivate do not skip further until json loads, for this I put a check if canActivate is not undefined, it returned false, but in the console it outputs that canActivate is passed and with the value undefined. What I'm doing is wrong, I'll be grateful for help, thanks.
My http-data.service
import {Injectable} from '#angular/core';
import {Http} from '#angular/http';
import {Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from "#angular/router";
#Injectable()
export class HttpService implements CanActivate{
constructor(private http: Http) {}
dataModules = this.getDataModules();
dataPresets = this.getDataPresets();
dataModuleItems = this.getDataModuleItems();
data: any[];
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean> | boolean {
if (this.getDataModules !== undefined) {
console.log('canActivate');
console.log(this.getDataModules());
return true;
} else return false;
}
getDataOrganizations(): Observable<any[]>{
return this.http.get('http://localhost:3010/data')
.map((resp:Response)=>{
let dataOrganizations = resp.json().organization;
return dataOrganizations;
});
}
loadDataModules(): Observable<any[]> {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let dataModules = resp.json().modules;
return dataModules;
});
}
loadDataPresets(): Observable<any[]> {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let dataPresets = resp.json().presets;
return dataPresets;
});
}
loadDataModuleItems(): Observable<any[]> {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let dataModuleItems = resp.json().module_items;
return dataModuleItems;
});
}
loadData() {
return this.http.get('http://localhost:3010/data')
.map((resp: Response)=> {
let data = resp.json();
return data;
});
}
getDataModules(): any[] {
this.loadDataModules().subscribe(((modules)=>{this.dataModules = modules; console.log('в http modules');console.log(this.dataModules);}));
return this.dataModules;
}
getDataPresets(): any[] {
this.loadDataPresets().subscribe(((presets)=>{this.dataPresets = presets; console.log(this.dataPresets);}));
return this.dataPresets;
}
getDataModuleItems(): any[] {
this.loadDataModuleItems().subscribe(((moduleItems)=>{this.dataModuleItems = moduleItems; console.log(this.dataModuleItems);}));
return this.dataModuleItems;
}
}
]2
Until you subscribe to the response your data will be undefined
getDataOrganizations(): Observable<any[]>{
let dataOrganizations :any[]
return this.http.get('http://localhost:3010/data')
.map(response => response.json().organization)
.subscribe(data => {
dataOrganizations = data;
return dataOrganizations;
});
}
Now you will get the object
Related
I want to add my website a user's profile updater. But when I try to open user's profile in my website, I have that error in Angular:
main.ts:6 ERROR SyntaxError: Unexpected token 'e', "eyJhbGciOi"... is not valid JSON
at JSON.parse (<anonymous>)
at LocalStorageService.getItem (local-storage.service.ts:17:22)
at get getDecodedToken [as getDecodedToken] (auth.service.ts:39:42)
at get getCurrentUserId [as getCurrentUserId] (auth.service.ts:44:29)
at UserComponent.getUserById (user.component.ts:51:51)
at UserComponent.ngOnInit (user.component.ts:28:10)
at callHook (core.mjs:2752:22)
at callHooks (core.mjs:2721:17)
at executeInitAndCheckHooks (core.mjs:2672:9)
at refreshView (core.mjs:12084:21)`
My local-storage.service.ts:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class LocalStorageService {
constructor() { }
setItem(key:string, value:any){
let json = JSON.stringify(value);
localStorage.setItem(key, json);
}
getItem(key:string){
let json = localStorage.getItem(key);
let value = JSON.parse(json);
return value;
}
isSaved(key: string) {
if (localStorage.getItem(key)) {
return true;
}
return false;
}
remove(key: string) {
localStorage.removeItem(key);
}
removeAll() {
localStorage.clear();
}
}
auth.service.ts:
`import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { LoginModel } from '../models/loginModel';
import { SingleResponseModel } from '../models/singleResponseModel';
import { TokenModel } from '../models/tokenModel';
import { LocalStorageService } from './local-storage.service';
import { UserPasswordModel } from '../models/userPasswordModel';
import { ResponseModel } from '../models/responseModel';
import { JwtHelperService } from '#auth0/angular-jwt';
#Injectable({
providedIn: 'root'
})
export class AuthService {
apiUrl="https://localhost:5001/api/auth/";
public jwtHelperService: JwtHelperService = new JwtHelperService();
constructor(private httpClient:HttpClient,
private localStorageService:LocalStorageService) {}
login(user:LoginModel){
return this.httpClient.post<SingleResponseModel<TokenModel>>(this.apiUrl+"login", user);
}
isAuthenticated(){
if (localStorage.getItem("token")) {
return true;
}else{
return false;
}
}
updatePassword(userPasswordModel:UserPasswordModel){
let newUrl = this.apiUrl + "updatepassword";
return this.httpClient.post<ResponseModel>(newUrl, userPasswordModel)
}
get getDecodedToken() {
let token = this.localStorageService.getItem("token");
return this.jwtHelperService.decodeToken(token);
}
get getCurrentUserId() {
let decodedToken = this.getDecodedToken;
let userIdString = Object.keys(decodedToken).filter((t) =>
t.endsWith('/nameidentifier')
)[0];
let userId: number = decodedToken[userIdString];
return userId;
}
}
user.component.ts:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { ToastrService } from 'ngx-toastr';
import { User } from 'src/app/models/user';
import { AuthService } from 'src/app/services/auth.service';
import { ProfileService } from 'src/app/services/profile.service';
#Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
user:User;
profileForm:FormGroup;
passwordForm:FormGroup;
dataLoaded = false;
constructor(
private userService:ProfileService,
private authService:AuthService,
private formBuilder:FormBuilder,
private toastrService:ToastrService
) { }
ngOnInit(): void {
this.getUserById();
this.createProfileForm();
this.createPasswordForm();
}
createProfileForm(){
this.profileForm = this.formBuilder.group({
id:[Number(this.authService.getCurrentUserId)],
firstName: ["",Validators.required],
lastName:["",Validators.required]
})
}
createPasswordForm(){
this.passwordForm = this.formBuilder.group({
userId:[Number(this.authService.getCurrentUserId)],
oldPassword: ["",Validators.required],
newPassword:["",Validators.required],
repeatNewPassword:["",Validators.required]
})
}
getUserById(){
this.userService.getUserById(this.authService.getCurrentUserId)
.subscribe(response=>{
this.user = response.data
this.dataLoaded = true
});
}
updateUserNames(){
if (this.profileForm.valid) {
let userModel = Object.assign({}, this.profileForm.value);
this.userService.updateUserNames(userModel).subscribe(response=>{
this.toastrService.info(response.message, "Bilgiler Güncellendi.");
setTimeout(() => {
window.location.reload();
}, 1000);
}, responseError=>{
console.log(responseError);
this.toastrService.error(responseError.error, "Hata!");
});
} else {
this.toastrService.error("Lütfen tüm alanları doldurunuz.", "Hata!");
}
}
updatePassword(){
if (this.passwordForm.valid) {
let passwordModel = Object.assign({}, this.passwordForm.value);
console.log(passwordModel);
this.authService.updatePassword(passwordModel).subscribe(response=>{
this.toastrService.info(response.message, "Şifre Güncellendi");
}, responseError=>{
this.toastrService.error(responseError.error, "Hata!");
});
} else {
this.toastrService.error("Lütfen tüm alanları doldurunuz.", "Hata!");
}
}
}
How can I fix this error? Thanks. I tried lots of thins, but no-one helped me.
I am trying to add a user's profile updater. But this error...
As the error says; Unexpected token 'e', "eyJhbGciOi"... is not valid JSON. You are trying to parse a plain string represents token itself, not a valid string represents a json object.. Therefore it fails when trying to parse it.
Either update the code where you directly store your token as string on your local storage or just use localStorage.getItem('token') without parsing.
Im just trying to sort this with no luck how to understand this async await promisse
this method will be used to call a dialog material before the update operation. The dialog has a subscribe and this is the reason I`m using this async await here.
this is the code:
async execute(task: ITask): Promise<boolean> {
return new Promise((resolve) => {
this.confirmation
.confirmDelete(`${task.id} - ${task.title}`)
.subscribe(async (confirmed) => {
if (confirmed) {
await this.repository.update(**<Task[]**>(task.id));
this.dialogService
.openConfirmDialog('Are you really want to delete/update/create?')
.afterClosed();
}
resolve(confirmed);
});
});
}
}
How to pass a object there in <Task[]>
I apreciate your help
Thanks
edited:
this is the task.repository.ts
import { environment } from './../../../environments/environment';
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { ITask } from '../models/itask';
#Injectable({
providedIn: 'root',
})
export class TaskRepository {
constructor(private httpClient: HttpClient) {}
create(task: ITask): Promise<ITask> {
return this.httpClient
.post<ITask>(`${environment.api}/tasks`, task)
.toPromise();
}
update(entity: ITask): Promise<ITask> {
const { id, ...data } = entity;
return this.httpClient
.put<ITask>(`${environment.api}/tasks/${id}`, data)
.toPromise();
}
getById(id: string): Promise<ITask> {
return this.httpClient
.get<ITask>(`${environment.api}/tasks/${id}`)
.toPromise();
}
getAll(): Promise<ITask[]> {
return this.httpClient
.get<ITask[]>(`${environment.api}/tasks/`)
.toPromise();
}
async delete(id: string): Promise<void> {
await this.httpClient.delete(`${environment.api}/tasks/${id}`).toPromise();
return;
}
}
Updated 2
using task as a parameter, solve the problem, but here at my .ts component start to complaim
import { ITask } from './../../models/itask';
import { GetTaskHandler } from './../../business-rules/get-task.handler';
import { UpdateTaskHandler } from './../../business-rules/update-task.handler';
import { CreateTaskHandler } from './../../business-rules/create-task.handler';
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormControl } from '#angular/forms';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-task-form-page',
templateUrl: './task-form-page.component.html',
styleUrls: ['./task-form-page.component.scss'],
})
export class TaskFormPageComponent implements OnInit {
pageTitle = 'Nova tarefa';
// configuração do formulário
form = this.formBuild.group({
title: [''],
description: [''],
done: [false],
});
get title(): FormControl {
return this.form.get('title') as FormControl;
}
get description(): FormControl {
return this.form.get('description') as FormControl;
}
get done(): FormControl {
return this.form.get('done') as FormControl;
}
taskId: string | undefined = undefined;
constructor(
private formBuild: FormBuilder,
private activatedRouter: ActivatedRoute,
private createTaskHandler: CreateTaskHandler,
private updateTaskHandler: UpdateTaskHandler,
private getTaskHandler: GetTaskHandler,
) {}
async ngOnInit(): Promise<void> {
const paramId = this.activatedRouter.snapshot.paramMap.get('id');
if (paramId) {
this.taskId = paramId;
await this.loadTask();
}
}
async loadTask(): Promise<void> {
const response = await this.getTaskHandler.execute(this.taskId || '');
if (response) {
this.pageTitle = 'Editando tarefa';
// atualizando o formulário com os valores retornados pela api
this.form.patchValue({
title: response.title,
description: response.description,
done: response.done,
});
}
}
async onSubmit(): Promise<void> {
const taskToSave: ITask = {
...this.form.value, // pegando todos os valores do formulário
id: this.taskId, // atualizando o id caso exista
};
let response: ITask | undefined;
if (taskToSave.id) {
***response*** = await this.updateTaskHandler.execute(taskToSave);
} else {
response = await this.createTaskHandler.execute(taskToSave);
}
if (response) {
this.taskId = response.id;
}
}
}
I think you made an error, update expects ITask object, so await this.repository.update(**<Task[]**>(task.id)); should be await this.repository.update(task); also I don't think it's a good idea to use a subscription inside a promise. so can you try something like this
async execute(task: ITask): Promise<boolean> {
// Convert to promise
const confirmed = await this.confirmation
.confirmDelete(`${task.id} - ${task.title}`).pipe(first()).toPromise();
if (confirmed) {
await this.repository.update(task);
this.dialogService.openConfirmDialog('Are you really want to delete/update/create?')
.afterClosed();
}
return new Promise((resolve) => {
resolve(confirmed);
});
});
}
}
You should use await this.repository.update(task);.
Dear I am developing a page with Angular 7 and I am presented with the error TS2559: Type 'BookInterface[]' has no properties in common with type 'BookInterface', I have changed the code but I still can not find the solution, I leave the code below, the error is thrown in the method getListBooks(): this is my file list-books.component.ts
import { BookInterface } from './../../../models/book';
import { DataApiService } from './../../../services/data-api.service';
import { Component, OnInit } from '#angular/core';
import {NgForm} from '#angular/forms';
#Component({
selector: 'app-list-book',
templateUrl: './list-book.component.html',
styleUrls: ['./list-book.component.css']
})
export class ListBookComponent implements OnInit {
constructor(private dataApi: DataApiService) { }
private books: BookInterface = {};
ngOnInit() {
this.getListBooks();
}
getListBooks() {
this.dataApi.getAllBooks().subscribe(books => {
this.books = books;
});
}
onDelete() {
console.log('LIBRO ELIMINADO');
}
}
I also leave the code of my data-api.service.ts from where I call the interface
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs/internal/Observable';
import { Injectable } from '#angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '#angular/fire/firestore';
import { BookInterface } from '../models/book';
#Injectable({
providedIn: 'root'
})
export class DataApiService {
constructor(private afs: AngularFirestore) {
this.bookCollecction = afs.collection<BookInterface>('books');
this.books = this.bookCollecction.valueChanges();
}
private bookCollecction: AngularFirestoreCollection<BookInterface>;
private books: Observable<BookInterface[]>;
private bookDoc: AngularFirestoreDocument<BookInterface>;
private book: Observable<BookInterface>;
getAllBooks() {
return this.books = this.bookCollecction.snapshotChanges()
.pipe(map( changes => {
return changes.map( action => {
const data = action.payload.doc.data() as BookInterface;
data.id = action.payload.doc.id;
return data;
});
}));
}
// metodo que trae un libro a traves de su id
getOneBook(idBook: string) {
this.bookDoc = this.afs.doc<BookInterface>(`books/${idBook}`);
return this.book = this.bookDoc.snapshotChanges().pipe(map(action => {
if (action.payload.exists === false){
return null;
} else {
const data = action.payload.data() as BookInterface;
data.id = action.payload.id;
return data;
}
}));
}
addBook(book: BookInterface): void {
this.bookCollecction.add(book);
}
updateBook(book: BookInterface): void {
let idBook = book.id;
this.bookDoc = this.afs.doc<BookInterface>(`books/${idBook}`);
this.bookDoc.update(book);
}
deleteBook(idBook: string): void {
this.bookDoc = this.afs.doc<BookInterface>(`books/${idBook}`);
this.bookDoc.delete();
}
}
The version of typescript that I am currently using is Version 2.7.2, but also update it without solving the problem
You need to change the following:
private books: BookInterface = {};
to:
private books: BookInterface[] = [];
This code throws an error in the method of "populateGridRows()", at the line of “row.setCompuetedProperties();”. The error message is – “ERROR TypeError: row.setCompuetedProperties is not a function”.
I can see all the properties (with data) on the “row” object in the console just before I get the error.
As far as I can understand it is all about mapping the JSON data coming from the server into a class. Please let me know where I have made a mistake. Thanks.
delivery-plan.component.ts
import { Component, OnInit, ViewChild, ViewEncapsulation } from "#angular/core";
import { ActivatedRoute } from "#angular/router";
import { DetailRow, ExcelExportProperties, FilterSettingsModel, Grid, GridComponent, GridLine, PdfExportProperties } from "#syncfusion/ej2-ng-grids";
import { ClickEventArgs } from '#syncfusion/ej2-ng-navigations';
import { UtilService } from "../../../shared/services/util.service";
import { ConditionBasedMaintenanceStatusEnum } from "../../enums";
import { ConditionAssessmentService, IConditionBasedMaintenanceRowModel } from "../../services/conditionassessment.service";
import { DeliveryPlanModel, DeliveryPlanService, IDeliveryPlanModel } from "../../services/delivery-plan.service";
#Component({
encapsulation: ViewEncapsulation.None,
selector: 'app-delivery-plan',
templateUrl: './delivery-plan.component.html',
styleUrls: ['./delivery-plan.component.scss']
})
export class DeliveryplanComponent implements OnInit {
schoolNumber: number;
deliveryPlanItems: DeliveryPlanModel[];
componentVariables: ConditionAssessmentComponentVariables;
gridRows: Array<DeliveryPlanModel>;
#ViewChild("deliveryItemsGrid") deliveryItemsGrid: GridComponent;
progressValue1 = 100;
progressValue2 = 62;
clickedYear = null;
constructor(private route: ActivatedRoute, private svcConditionAssessment: ConditionAssessmentService,
private svcUtil: UtilService, private deliveryPlanService: DeliveryPlanService) {
this.componentVariables = new ConditionAssessmentComponentVariables();
this.gridRows = new Array<DeliveryPlanModel>();
}
ngOnInit() {
this.route.parent.params.subscribe(params => {
this.schoolNumber = parseInt(params["id"]);
});
Grid.Inject(DetailRow);
this.getDeliveryPlanItems();
}
public getDeliveryPlanItems() {
this.deliveryPlanService
.getDeliveryPlanItems(this.schoolNumber.toString()).subscribe(
data => {
if (data) {
this.deliveryPlanItems = data;
this.populateGridRows();
}
}
)
}
public populateGridRows(): void {
if (this.deliveryPlanItems && this.deliveryPlanItems.length) {
for (var i = 0; i < this.deliveryPlanItems.length; i++) {
let row = this.deliveryPlanItems[i];
console.log(row);
row.setCompuetedProperties(); // The Error is associated with this line
this.gridRows.push(row);
}
}
}
delivery-plan.service.ts
import { HttpClient, HttpHeaders, HttpParams } from "#angular/common/http";
import { Injectable } from "#angular/core";
import { Router } from '#angular/router';
import { Observable, Operator } from "rxjs";
import { ErrorsService } from "../../shared/services/errors.service";
import { ConditionBasedMaintenanceStatusEnum } from "../enums";
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
export interface IDeliveryPlanModel {
//Props
type: string;
id: number;
buildingName: string;
location: string;
asset: string;
element: string;
subElement: string;
description: string;
trade: string;
status: number;
statusDisplay: string;
plannedDate: Date;
completedDate: Date;
deferred: boolean;
// methods
setCompuetedProperties(): void;
}
export class DeliveryPlanModel implements IDeliveryPlanModel {
//Props
type: string = null;
id: number = null;
buildingName: string = null;
location: string = null;
asset: string = null;
element: string = null;
subElement: string = null;
description: string = null;
trade: string = null;
status: number = null;
statusDisplay: string = null;
plannedDate: Date = null;
completedDate: Date = null;
deferred: boolean = null;
color: string = null;
// methods
public setCompuetedProperties(): void {
switch (this.status) {
case ConditionBasedMaintenanceStatusEnum.AddedToPlanner:
this.statusDisplay = "Planned";
break;
case ConditionBasedMaintenanceStatusEnum.Deferred:
this.statusDisplay = "Deferred";
break;
case ConditionBasedMaintenanceStatusEnum.Completed:
this.statusDisplay = "Completed";
break;
}
}
}
#Injectable()
export class DeliveryPlanService {
routePrefix: string = "api/deliveryplans";
constructor(private http: HttpClient, private router: Router, private errorsService: ErrorsService) { }
public getDeliveryPlanItems(schoolId: string): Observable<DeliveryPlanModel[]> {
var list = this.http.get<DeliveryPlanModel[]>(this.routePrefix + "/schools/" + schoolId)
.map<DeliveryPlanModel[], DeliveryPlanModel[]>(items => {
return items;
}).catch(error => this.errorsService.handleError(error));
return list;
}
}
I have a issue when I try to do the login. Step by step:
- The user clicks the login button;
- Auth0 appears to do the login;
- The user profile is saved in localStorage;
- When login is successful the internal page is loaded and the user can use the system. Every page need the profile data (in localStorage).
The problem
It's impossible to enter in the system in the first login. IT's EMPTY!!! even if the login was successful! I set a flow to logout the system when the localStorage is empty, so it's redirect to the login page.
BUT when you try again, everything goes fine! I have no idea why.
Follows the code.
AuthService
import { Injectable } from '#angular/core';
import { Router } from '#angular/router';
import { ApiService } from './api.service';
import { Profile } from '../models/Profile';
import auth0 from 'auth0-js';
import 'rxjs/add/operator/filter';
#Injectable()
export class AuthService {
auth0 = new auth0.WebAuth({
// Credentials
});
constructor(protected router: Router, protected api: ApiService) {}
public login(): void {
this.auth0.authorize();
}
public logout(): void {
localStorage.removeItem('profile');
localStorage.removeItem('id_token');
localStorage.removeItem('expires_at');
localStorage.removeItem('access_token');
this.router.navigate(['/']);
}
private setSession(authResult): void {
const profile = authResult.idTokenPayload;
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
localStorage.setItem('expires_at', expiresAt);
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('access_token', authResult.accessToken);
this.api.getUsuario(profile.name)
.subscribe(res => {
profile.nivel = res.nivel;
profile.idClube = res.idClube;
localStorage.setItem('profile', JSON.stringify(profile));
});
}
public handleAuthentication(): void {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
window.location.hash = '';
this.setSession(authResult);
this.router.navigate(['/calendario_']);
} else if (err) {
this.router.navigate(['/login']);
console.error(err);
}
});
}
public isAuthenticated(): boolean {
const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
return new Date().getTime() < expiresAt;
}
}
LoginComponent
import { Component } from '#angular/core';
import { AuthService } from '../../services/auth.service';
#Component({
moduleId: module.id,
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
constructor(protected auth: AuthService) { }
}
Component (After successful login)
import { Component, OnInit } from '#angular/core';
import { Profile } from '../../models/Profile';
import { Calendario } from '../../models/Calendario';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';
#Component({
moduleId: module.id,
selector: 'app-calendarioproximo',
templateUrl: './calendarioProximo.component.html'
})
export class CalendarioProximoComponent implements OnInit {
protected title: string;
protected dataAtual: any;
protected loading = true;
protected profile: Profile;
protected model: Calendario[] = [];
protected calendario: Calendario[] = [];
constructor(protected api: ApiService, protected auth: AuthService) { }
getCalendario() {
this.api.getCalendario(this.profile.idClube)
.subscribe(res => {
this.loading = true;
this.model = res;
this.api.getData()
.subscribe(data => {
this.dataAtual = data.dataCompleta;
for (let cont = 0; cont < this.model.length && this.calendario.length < 5; cont++) {
if (this.model[cont].data >= this.dataAtual) {
this.calendario[this.calendario.length] = this.model[cont];
}
}
this.loading = false;
}, err => console.error(err));
});
}
ngOnInit() {
this.title = 'Calendário Próximo';
this.profile = new Profile();
// HERE!
JSON.parse(localStorage['profile']) ? this.profile = JSON.parse(localStorage['profile']) : this.auth.logout();
this.getCalendario();
window.scrollTo(0, 0);
}
}
Your setSession(authResult) function does not save the profile at the same time when it saves expires_at, id_token, and access_token.
The assignment will happen eventually, as a part of the handler in
getUsuario(profile.name).subscribe(() => {...})`.
Moving this.router.navigate(['/calendario_']); from handleAuthentication into setSession may resolve your issue:
private setSession(authResult): void {
const profile = authResult.idTokenPayload;
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
localStorage.setItem('expires_at', expiresAt);
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('access_token', authResult.accessToken);
this.api.getUsuario(profile.name)
.subscribe(res => {
profile.nivel = res.nivel;
profile.idClube = res.idClube;
localStorage.setItem('profile', JSON.stringify(profile));
this.router.navigate(['/calendario_']); // Navigate after you `profile` has been set for sure
});
}
public handleAuthentication(): void {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
window.location.hash = '';
this.setSession(authResult);
// this.router.navigate(['/calendario_']); // This is too early...
} else if (err) {
this.router.navigate(['/login']);
console.error(err);
}
});
}