3

I have written a very simple component that includes a variable to keep track of state. When the value changes the UI is supposed to display different content accordingly. To test out the functionality I created the component, and am using a wait function to update the value after 5 seconds. While the variable is getting changed (I validated the change by logging it to the console), it does not seem to trigger a UI refresh. I have a hunch that I need to make the variable an observable, but I am not sure if that is overkill and if there is a simpler solution. Here is the code for my component

import { Component, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material';

@Component({
  selector: 'app-export',
  templateUrl: './export.component.html',
  styleUrls: ['./export.component.scss']
})
export class ExportComponent implements OnInit {

  flowId: number;

  constructor(public snackBar: MatSnackBar) {
    this.flowId = 1;
  }

  ngOnInit() {}

  incrementFlowID() {
    this.flowId++;
    console.log(this.flowId);
  }

  openSnackBar(message: string, action: string) {
    const snackBarRef = this.snackBar.open(message, action, {duration: 5000, });
    snackBarRef.afterDismissed().subscribe(() => {
      this.incrementFlowID();
    });
  }

  initiateExport() {
    this.incrementFlowID();
    this.openSnackBar('Your pdf document is being generated', '');
  }

}

The corresponding HTML snippet that is relevant here looks as follows:

    <div *ngIf="this.flowId == 1">
      <button mat-raised-button (click)="initiateExport()">Create PDF</button>
    </div>
    <div *ngIf="this.flowId == 2">
      <b>Your pdf document is being created.</b>
    </div>
    <div *ngIf="this.flowId == 3">
      <b>PDF document is complete.</b> <br/>
      <a href="#">Download document</a><br/>
    </div>

It seems while the event of "afterDismissed" properly updates the ID number, the change of the variable does not trigger a repainting of the UI. Any help on how to solve this would be greatly appreciated.

1
  • If the posted answer doesn't helped then provide stackblitz demo Commented Jan 11, 2020 at 5:10

1 Answer 1

7

Remove 'this' from your html

<div *ngIf="flowId == 1">
  <button mat-raised-button (click)="initiateExport()">Create PDF</button>
</div>
<div *ngIf="flowId == 2">
  <b>Your pdf document is being created.</b>
</div>
<div *ngIf="flowId == 3">
  <b>PDF document is complete.</b> <br/>
  <a href="#">Download document</a><br/>
</div>

I see now, add this to your component. Working Link

import {Component, ViewEncapsulation, ChangeDetectorRef} from '@angular/core';

...
constructor(
public snackBar: MatSnackBar,
private ref: ChangeDetectorRef
) {
  this.flowId = 1;
}

...

openSnackBar(message: string, action: string) {
  const snackBarRef = this.snackBar.open(message, action, {duration: 5000, });
  snackBarRef.afterDismissed().subscribe(() => {
    this.incrementFlowID();
    this.ref.detectChanges();
  });
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the suggestion, but removing 'this' still shows the same problem. The flowID is updated properly either way. The ngif fires when the value goes from 1 to 2 (it did so with the this and without the this), but does not update when the value changes from 2 to 3.
does the console.log(this.flowId); log 2, then 3 in your method: incrementFlowID?
Yes it does. The flowId is incremented properly. Clicking on the button on the screen increments the number and the event of clicking causes the DOM to be updated properly. On the subscribed event from the timer though the flowId updates from 2 to 3, yet the UI does not change.
Fantastic. Thanks for the help. Learned something new with the user of ChngeDetectRef and ViewEncapsulation. Much appreciated.
ViewEncapsulation was not meant to be part of answer. You can remove that and it will still work. ViewEncapsulation is only for scoping CSS to the component and it's children.

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.