Mands
Mands

Reputation: 221

How to update the html page view after a timeout in Angular

I am trying to display a routerlink name based on a condition. I want to display the div section routerLink name if condition is true.If i check {{isNameAvailable}}, first it displays false and after this.names got the values it shows true.Since in the component getDetails() method is asynchronous this.names getting the values after html template render.Therefore this routerLink does n't display.Therefore I want to display div section after some time. (That 's the solution i have) Don't know whether is there any other solution.

This is my html file code.

<main class="l-page-layout ps-l-page-layput custom-scroll bg-white">
     {{isNameAvailable}}
<div class="ps-page-title-head" >
      <a *ngIf ="isNameAvailable === true" [routerLink]="['/overview']">{{Name}} &nbsp;                         
      </a>
  {{Name}} 
</div>
</main>

This is my component.ts file

names= [];
isNameAvailable = false;

ngOnInit() {
  this.getDetails()
}

getDetails() {
  this.route.params.subscribe(params => {
     this.names.push(params.Names);
     console.log(this.names);
     this.getValues().then(() => {
                        this.isNameAvailable = this.checkNamesAvailability(this.names);
                        console.log(this.isNameAvailable);                                      
                        });
   });
}
 resolveAfterSeconds(x) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(x);
        }, 900);
    });
}
checkNamesAvailability(names) {
        console.log(names);
        return names.includes('Sandy');
    }
 async getValues() {
    await this.resolveAfterSeconds(900);
}

And console.log(this.isLevelAvailable); also true. What I can do for this?

Upvotes: 1

Views: 1766

Answers (3)

Eran Eichenbaum
Eran Eichenbaum

Reputation: 161

1.You do not have anything to show in the HTML only the isNameAvailable, because you do not have any assignment in the Name variable.

2.It is better to use the angular build-in async pipe, when you want to show the returned value from observables.

3.When you are using the *ngIf directive you can skip *ngIf ="isNameAvailable === true" check because the variable is boolean type, you gust write *ngIf ="isNameAvailable", it will check also for null but NOT for undefined

  1. It is working because the *ngIf directive is responsible for checking and rendering the UI, you can see how many times the directive is checking by calling an function and print and answer in the console.

Upvotes: 2

Barremian
Barremian

Reputation: 31115

You could use RxJS timer function with switchMap operator instead of a Promise to trigger something after a specific time.

Try the following

import { Subject, timer } from 'rxjs';
import { takeUntil, switchMap } from 'rxjs/operators';

names= [];
isNameAvailable = false;
closed$ = new Subject();

ngOnInit() {
  this.getDetails()
}

getDetails() {
  this.route.params.pipe(
    switchMap((params: any) => {
      this.names.push(params.Names);
      return timer(900);       // <-- emit once after 900ms and complete
    }),
    takeUntil(this.closed$)    // <-- close subscription when `closed$` emits
  ).subscribe({
    next: _ => {
      this.isNameAvailable = this.checkNamesAvailability(this.names);
      console.log(this.isNameAvailable);
    }
  });
}

checkNamesAvailability(names) {
  console.log(names);
  return names.includes('Sandy');
}

ngOnDestroy() {
  this.closed$.next();         // <-- close open subscriptions when component is closed
}

Upvotes: 0

Bidyn
Bidyn

Reputation: 149

By any chance do you have changeDetection: ChangeDetectionStrategy.OnPush docs set in component annotation? That might explain this behaviour. With it Angular run change detection only on component @Input()'s changes and since in your case there were non it did not run change detection which is why template was not updated. You could comment that line to check if that was cause of the issue. You are always able to run change detection manually via ChangeDetectorRef.detectChange() docs which should solve you problem

constructor(private cd: ChangeDetectorRef) {}
...
    getDetails() {
          this.route.params.subscribe(params => {
             ...
             this.getValues().then(() => {
                                this.isNameAvailable = this.checkNamesAvailability(this.names);
                                this.cd.detectChanges(); // solution
                                console.log(this.isNameAvailable);                                      
                                });
           });
        }

This stackblitz show this bug and solution. You can read more about change detection here

Upvotes: 1

Related Questions