0

I am new to Angular. I am trying to change the layout of the my webpage based on whether a user is logged in or logged out. However this can be done only when the 'true' of 'false' is retrieved from the server. How can I do that? The TS code snippet is:

lgn: boolean;

ngOnInit(): void {
    this.auth.onAuthStateChanged((user) => {
      if (user) {
        this.lgn = true;
      } else {
        this.lgn = false;
      }
    });
  }

The HTML code snippet is:

<div *ngIf="lgn; then thenBlock; else elseBlock"></div>
  <ng-template #thenBlock>Logged In</ng-template>
  <ng-template #elseBlock>Not logged in</ng-template>

However this always shows 'Not logged in'.

4
  • Can you share your onAuthStateChanged method please Commented Jul 29, 2020 at 9:47
  • The onAuthStateChanged method is taken from @angular/fire package. github.com/firebase/angularfire/blob/master/docs/… Commented Jul 29, 2020 at 9:51
  • Have you tried to add some console.log into your if else statement to check if it goes into it ? And also console.log your user ? Commented Jul 29, 2020 at 9:55
  • The console.log shows true when logged in and false when logged out. However the HTML file is rendered first before data is retrieved from the server. So it is a case where not logged in is displayed first and then the boolean value is retrieved. I want it to be the other way i.e., first data is received and then page is rendered. Commented Jul 29, 2020 at 10:01

2 Answers 2

1

You need to use Route Resolver to load the user data before you arrive at the component:

  1. Implement a resolver service first:

@Injectable({
    providedIn: 'root'
})
export class UserResolverService implements Resolve<any> {
    constructor(private auth: AngularFireAuth) { }
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        return this.auth.authState;
    }
}
  1. Add the service to your routing:
const routes: Routes = [
    {
        path: 'somepath',
        component: SomeComponent,
        resolve: {
            user: UserResolverService
        }
    }
];
  1. Now you can get the data right after you arrived at the component:
user: any;

constructor(
    private route: ActivatedRoute
) { }

ngOnInit() {
    this.user = this.route.snapshot.data.user;
}
Sign up to request clarification or add additional context in comments.

3 Comments

I tried the subscribe method earlier. It works fine but the problem is that the webpage loads first, then data is retrieved and then the status is changed to logged in. Is there a way such that page will be rendered only after data is retrieved?
What you want is to use router resolver which will prevent your navigation before a data is arrived.
Also you could use routing guard to archieve this.
0

Sounds like your server call is always returning false - I would confirm this works first using a console log...

And I'd probably write your html like this

<div *ngIf="lgn; else elseBlock">
Logged In
</div>
  <ng-template #elseBlock>Not logged in</ng-template>

2 Comments

I checked with console.log. The server returns true when user is logged in. I think this is a case where the webpage is rendered first and then data is retrieved from the system.
yes you are doing a syncronous call... you should be subscribing using rxjs and then it will work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.