user11002299
user11002299

Reputation: 33

Angular doesn't update the view on arrival of new data

I've defined a search-input field in the navbar: <input type="search" class="form-control" [formControl]="search" placeholder="search" aria-label="search">

In its controller I subscribe for changes and forward them to the search service:

this.search
  .valueChanges
  .subscribe(v => {
    this.searchService.setSearchValue(v);

    if (this.changeDetectorRef !== null && this.changeDetectorRef !== undefined &&
      !(this.changeDetectorRef as ViewRef).destroyed) {
      this.changeDetectorRef.detectChanges();
    }
  });
}

The search service holds the value and other components can request it.

searchValue: Subject<string>;

getSearchValue(): Observable<string> {
    return this.searchValue;
}

setSearchValue(searchValue: string) {
    this.searchValue.next(searchValue);
}

In my data view, I display all data filtered by the search-value:

<div *ngIf="(services | search:searchValue) as result">
    <div *ngFor="let service of result">
        {{ service.name }}
    </div>
</div>
this.searchService.getSearchValue().subscribe(value => {
    console.log("new search value: " + value);
    this.searchValue = value;
});

The view doesn't update on the first keystroke however, and only updates itself after the second one.

I know that the correct search value arrives at the component as the console.log contains the expected value, but the view is nevertheless not updated. I've also tried changeDetectorRef.detectChanges() and searchPipe.transform(this.services, value) in my view but without success.

Could anyone tell me what went wrong? Thanks in advance.

Upvotes: 2

Views: 326

Answers (2)

Dmitry Sobolevsky
Dmitry Sobolevsky

Reputation: 1191

Firstly. you don't have to use such a piece of code:

      if (this.changeDetectorRef !== null && this.changeDetectorRef !== undefined &&
          !(this.changeDetectorRef as ViewRef).destroyed) {
          this.changeDetectorRef.detectChanges();
        }

I suppose sometimes you catch an exception, that's why you don't unsubscribe from this.search.valueChanges or you have logic that works very strange.

Try to use BehaviorSubject instead of Subject, difference being that Subject don't store the last emitted value, whereas BehaviorSubjects do. Maybe one of your component or service initializes faster than other components, and your Subject already fired value.

Upvotes: 1

Rahul Tokase
Rahul Tokase

Reputation: 1218

Assuming your doing the below code in ngonInit

this.searchService.getSearchValue().subscribe(value => {
    console.log("new search value: " + value);
    this.searchValue = value;

    // Run the change detection here 
    this.changeDetectorRef.detectChanges();
});

Upvotes: 0

Related Questions