Stefa
Stefa

Reputation: 647

Angular SSR ngIf rendered when value is false

I got this weird stuff going on and I can't understand why

                {{!loggedIn}}
                <div class="flex gap-4" *ngIf="!loggedIn">
                    <button
                        [routerLink]="['/auth', 'register']"
                        class="cursor-pointer rounded bg-primary-100 px-4 py-2 text-primary-400 hover:bg-primary-50"
                    >
                        Get Started
                    </button>
                    <button
                        [routerLink]="['/auth', 'login']"
                        class="cursor-pointer rounded bg-primary-100 px-4 py-2 text-primary-400 hover:bg-primary-50"
                    >
                        Login
                    </button>
                </div>

Then I have

   ngOnInit () {
    this.loggedIn = false
    this.authStateService.subscribe(val=> {
        this.loggedIn = val.isAuthenticated;
    })
}

the result looks like this:

enter image description here

This is the bootstrap:

import { provideHttpClient, withFetch } from '@angular/common/http'
import { ApplicationConfig, mergeApplicationConfig } from '@angular/core'
import { provideClientHydration } from '@angular/platform-browser';
import { provideServerRendering } from '@angular/platform-server'
import { appConfig } from './app.config'

const serverConfig: ApplicationConfig = {
    providers: [
        provideServerRendering(),
        provideClientHydration(),
        provideHttpClient(withFetch()),
    ],
}

export const config = mergeApplicationConfig(appConfig, serverConfig)

Question is: why is it rendered, when it shouldn't be?

Upvotes: 1

Views: 188

Answers (2)

Alex M
Alex M

Reputation: 41

If you are using localStorage on Angular SSR it will not work because localStorage is available only on the client side.

Where are you getting the authentication value from ?

Upvotes: 0

Naren Murali
Naren Murali

Reputation: 57986

You can also use this.loggedIn$ = this.authStateService then use async pipe on the ngIf like <div class="flex gap-4" *ngIf="!(loggedIn$ | async)">

Another problem might be ngIf is true on the server, but false on the browser, to make html render only on the browser you can use @defer block

       @defer() {
            <div class="flex gap-4" *ngIf="!loggedIn">
                <button
                    [routerLink]="['/auth', 'register']"
                    class="cursor-pointer rounded bg-primary-100 px-4 py-2 text-primary-400 hover:bg-primary-50"
                >
                    Get Started
                </button>
                <button
                    [routerLink]="['/auth', 'login']"
                    class="cursor-pointer rounded bg-primary-100 px-4 py-2 text-primary-400 hover:bg-primary-50"
                >
                    Login
                </button>
            </div>
       }

Maybe your component is having change detection as OnPush so trigger a manual change detection, after the subscribe callback.

...
constructor(private cdr: ChangeDetectorRef) {}
...

...
ngOnInit () {
    this.loggedIn = false
    this.authStateService.subscribe(val=> {
        this.loggedIn = val.isAuthenticated;
        this.cdr.detectChanges();
    })
}

Upvotes: 0

Related Questions