Wondering how to force a page refresh?

I have searched the forum on this topic and have seen previous threads - so I know the issue is there.

One response was very pure - saying that no refresh should be needed - just update the state and angular should take care of refreshing the page.

However, that doesn’t seem to be the case.

I have a problem (in a web view) with recognizing login state with firebase. On the initial loading - the user appears not to be logged in, and only after some time goes by (using subscribe) does the state change to logged in.

My html uses *ngIf to show the user the login state - either the user isn’t - and is a guest - or he/she is - and I should their name in the caption.

I am not getting any refresh of the page when the state changes - so I’d like to force the update - but that seems difficult.

I saw someone suggest re-navigating to home, but that feels wrong to me. I also saw someone suggest calling ionViewDidEnter() again - but again this doesn’t feel right.

Just thought I would ask again - since some of the previous answers were specific to earlier version of ionic…

Is there a simple way to request a refresh of the page?

thanks in advance! This is probably a naive question -

I agree with that response, and it may well have been me who wrote it.

It should be the case, and so if it isn’t, then there is either a bug in a dependent library you’re using or in your app code. The way you’ll get the most productive assistance in diagnosing the situation is if you can make a publicly available minimal repository that reproduces the problem.

Hi! I love your response - I agree - it should “just work.”

I’m new to ionic and angular, so the chance that I’m doing something wrong is high. I’ll attach a bit of my code…

Here’s the html for the home screen header:

I’m trying to show the user that he/she’s either logged in - or is a guest.

In my ts file - that variable is initially false - but I subscribe to changes that will update that variable to true:

ngOnInit() {

this.authService.authenticationState.subscribe(state => {
console.log(‘main app Auth changed:’, state)
this.loggedIn = state;
}

}

I can tell from the console log that the variable does change - but the html doesn’t.

My desire is to have the page detect the state change and update itself - but it doesn’t.

Do I need to mark the variable differently or put the subscription somewhere else?

thanks so much for the help!

Unfortunately, in a situation like this, “a bit of the code” isn’t going to be sufficient. It has to be something that other people can easily build into a running application that demonstrates the problem.

Hi,

I have too much code to figure out how to make a snip that others could compile/run.

I had hoped I had provided enough. Not sure how to move forward - sorry.

In that case, the answer to the specific question you ask in your OP is Location.reload.

Using it in an Ionic app is a terribly wasteful idea that I would not recommend in any circumstances, but without access to a reproducible example that I can engage with, I can’t say anything actually constructive to your particular situation.

yes that’s disappointing. I doubt that will work, and I’m not really interested in such a kludge.

I know that just doing a refresh from the browser reproduces the same failure - so I suspect this wouldn’t solve things.

I like your attitude that it should just refresh - perhaps one day I’ll make some progress.

thanks for trying!

Again - I have limited experience - but this problem seems to be related to *ngIf.

As I understand angular - the concept of automatic refresh is related to changes in the dom - but perhaps it’s because there isn’t a change in the dom here. What has changed is a variable in the TS - but the dom was already created - and doesn’t know or care about local variables.

Perhaps I should try a more pure javascript idea - where I get a member of the dom using document.querySelector - and then directly modify .innerHTML.

I think I’ll try that. No idea how hard that will be - but I’m now thinking angular won’t help - because there isn’t any change in the dom - just because a state changed in some variable in TS.

No.

Emphatically no. Let the framework do its job.

No once more.

Here is a relatively complete example. Try running it in your environment and see how it behaves. Then try to augment it with just enough of your actual code to get it to the point where it behaves differently, and you should have isolated where your problem really lies.

auth-service.ts

export interface User {
  name: string;
}

@Injectable()
export class AuthService {
  user$ = new BehaviorSubject<User | undefined>(undefined);

  watchUser(): Observable<User | undefined> {
    return this.user$;
  }

  login(user: User): void {
    this.user$.next(user);
  }

  logout(): void {
    this.user$.next(undefined);
  }
}

home.page.ts


@UntilDestroy()
@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit, OnDestroy {
  activeUser?: User;
  userNameControl = new FormControl();

  constructor(private auther: AuthService) {
  }

  ngOnInit() {
    this.auther.watchUser().pipe(untilDestroyed(this)).subscribe(u => this.activeUser = u);
  }

  ngOnDestroy() {
  }

  login(): void {
    this.auther.login({name: this.userNameControl.value});
  }

  logout(): void {
    this.auther.logout();
  }
}

home.page.html

<ion-header>
  <ion-item color="danger" *ngIf="!activeUser">
    <ion-label>INTRUDER DETECTED</ion-label>
  </ion-item>
  <ion-item color="primary" *ngIf="activeUser">
    <ion-label>Hello {{activeUser.name}}</ion-label>
  </ion-item>
</ion-header>

<ion-content>
  <ng-container *ngIf="!activeUser; else loggedIn">
    <ion-item>
      <ion-label>user name</ion-label>
      <ion-input [formControl]="userNameControl"></ion-input>
    </ion-item>
    <ion-item button color="secondary" (click)="login()">log in</ion-item>
  </ng-container>
  <ng-template #loggedIn>
    <ion-item button color="secondary" (click)="logout()">log out</ion-item>
  </ng-template>
</ion-content>

wow! thanks for such a complete sample.

It’s eod so I won’t finish this today - but I will certainly compare this to my code. I was using BehaviorSubject - but I do see slight differences in my setup:

authenticationState = new BehaviorSubject(false);

I also didn’t have @UntilDestory - which is new to me. I will change my code to emulate yours.

Thanks so much - I’ll let you know (tomorrow) how this works out. I so appreciate the help.

It’s not strictly relevant to this particular issue, but is a nice clean way to deal with the problem of leaking subscriptions - the library is ngneat/until-destroy.

1 Like