Search code examples
angularasynchronouspipeobservableweb-component

Angular component containing async pipe: on-screen value never refreshed. How to deal with that?


I have an Angular component wrapping an 'async pipe' in order to perform some request on a REST API. My component is displaying a value according to given params. One of the inputs of my component is subject to change. When the value of the input is changing, my component is able to receive the new value and deal with it. But the displayed value is not refreshed according the new input.

Could you help me to find out what I'm doing wrong?

@Component({
  selector:'app-mycomponent',
  template: `
    <div>This is my Component
      <div style="text-align:center">
          <button (click)="changeValue(1)">ENGLISH</button>
          <button (click)="changeValue(2)">FRANCAIS</button>
      </div>
      <dl>
        <dt>
          Current value is:
        </dt>
        <dd>{{_currentValue}}</dd>
        <dt>
          Child value is:
        </dt>
        <dd><app-codereader name='customCode' value={{_currentValue}} [languageIsoCode]='languageIsoCode'></app-codereader></dd>
      </dl>
    </div>`
})
export class MyComponent {
  private _currentValue = 1;

  changeValue(newValue:numeric) {
    this._currentValue = newValue;
  }

  get languageIsoCode() {
    if (1 == this._currentValue) {
      return 'en';
    } else if (2 == this._currentValue) {
      return 'fr';
    }
    return undefined;
  }

}


@Component({
  selector: 'app-codereader',
  template: '<span>{{ observableRefData | async }}</span>'
})
export class CodeReaderComponent implements OnInit, OnChanges {
  @Input() name: string;
  @Input() value: any;
  @Input() languageIsoCode: string;

  observableRefData$: Observable<string>;

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.loadData();
  }

  ngOnChanges(changes: SimpleChanges) {
    if (this.observableRefData$ && changes.languageIsoCode && changes.languageIsoCode.currentValue) {
      this.observableRefData$.subscribe(data => {
        console.log('Lang has changed:', changes.languageIsoCode.currentValue);
        this.languageIsoCode = changes.languageIsoCode.currentValue;
        this.loadData;
      });
    }
  }

  loadData(){
    if (this.value && this.name && this.languageIsoCode) {
      console.log('Reload data', this.value, this.name, this.languageIsoCode);
      switch (this.name) {
        case 'customCode':
          this.observableRefData$ = this.dataService.searchForCategoryCode(this.value, this.languageIsoCode);
          break;
        default:
          //this.observableRefData$ = this.dataService.searchForXXX(this.name, this.code, this.languageIsoCode);
          break;
      }
    }
  }
}

Here's a plunkr to help you understand what I mean: editor / Embed

You'll see that every time you hit a 'language' button, value is changing, but displayed label (which is processed by my component) never change. I would like observableRefData to be changing.

Note that the button to switch languages is for example purposes. Don't suggest ngx-translate, that's not what I'm looking for.


Solution

  • On line 28 of your src/codereadercomponent.ts file you are missing the () from the end, so you are not calling a function, you are looking for a variable.

    You need to update line 28 to the following:-

    this.loadData()

    Here is the updated plunkr