1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

How to initialize a component after an injected service's constructor has completed

Discussão em 'Angular' iniciado por Oscar Blanchet, Maio 20, 2025.

  1. I am trying to make an API call to get an instance of a User interface from my backend. I have two services that are used in my component. UserService is used to obtain a User observable, and AuthService is used to authenticate the user using Keycloak. AuthService has a constructor function that checks if the user is authenticated and, if it is, fetches its username and user roles. Both of these services are injected in a Menu component has an ngOnInit method that checks if the user is authenticated using AuthService, then subscribes to the User observable from UserService, passing the authentication username obtained in the AuthService constructor as a parameter.

    MenuComponent:

    export class MenuComponent implements OnInit{
    private authService: AuthService = inject(AuthService);
    private userService: UserService = inject(UserService);
    private username:string|undefined;
    user: User | undefined;

    ngOnInit() {
    if (this.isAuthenticated()) {
    this.userService.getUser(this.getUsername()).subscribe({
    next: value => this.user = value,
    });
    }
    }

    isAuthenticated(){
    return this.authService.isAuthenticated();
    }

    getUsername(){
    return this.authService.getUsername();
    }
    }


    UserService:

    export class UserService {
    http = inject(HttpClient);
    urlGetUser = `${environment.resourceServer}/api/user/`;

    getUser(username: string | undefined):Observable<User>{
    return this.http.get<User>(this.urlGetUser + username);
    }
    }


    AuthService:

    export class AuthService {
    authenticated = false;
    username: string | undefined = "";
    keycloakStatus: string | undefined;
    private readonly keycloak = inject(Keycloak);
    private readonly keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);
    userRoles: string[] | undefined;
    constructor() {
    effect(() => {
    const keycloakEvent = this.keycloakSignal();

    this.keycloakStatus = keycloakEvent.type;

    if (keycloakEvent.type === KeycloakEventType.Ready) {
    this.authenticated = typeEventArgs<ReadyArgs>(keycloakEvent.args);
    if (this.authenticated){
    this.keycloak.loadUserProfile().then(userProfile =>
    { this.username=userProfile.username;
    this.userRoles = this.keycloak.realmAccess?.roles || [];
    }
    ).catch(
    error => {console.log(error);this.username="";}
    )

    }
    }

    if (keycloakEvent.type === KeycloakEventType.AuthLogout) {
    this.authenticated = false;
    this.username=""
    }

    });
    }

    isAuthenticated(){
    return this.authenticated;
    }

    getUsername() {
    return this.username??"";
    }


    My problem is that the ngOnInit funtion on MenuComponent seems to get called before the AuthService constructor finishes its execution. AuthService.isAuthenticated() returns true, but AuthService.getUsername() returns the default value, which means my api call always fails. Is there any way to make sure that MenuComponent is only initialized after the AuthService constructor has finised its execution?

    Continue reading...

Compartilhe esta Página