Currently, I am facing an issue while working on my Angular 4 application. I have noticed that I need to use
this.changeDetectorRef.detectChanges();
to update the view whenever there is a change in the model. This requirement arises in scenarios like pagination as shown below:
changePage(pageNumber) {
this.currentPage = pageNumber;
// Why is this necessary?
this.changeDetectorRef.detectChanges();
}
Even though I have set the change detection strategy of the component to ChangeDetectionStrategy.Default
, it does not seem to have any impact. The same issue occurs when subscribing to an observable:
showResults(preference) {
this.apiService.get('dining_autocomplete/', `?search=${preference}`)
.subscribe((results) => {
this.searchResults = results;
// Why do I need to do this?
this.changeDetectorRef.detectChanges();
});
}
When I log this.searchResults
in TypeScript, the expected results are obtained. However, the HTML does not get updated with {{ searchResults }}
until some other event triggers a digest cycle.
What could possibly be causing this behavior?
== EDIT ===========================================================
This is how my component's code appears:
import {ChangeDetectorRef, Component, Input, OnChanges} from "@angular/core";
import * as _ from 'lodash';
@Component({
selector: 'dining-search-results',
templateUrl: './dining-search-results.template.html',
styleUrls: ['./dining-search-results.style.scss'],
})
export class DiningSearchResultsComponent {
@Input() searchResults: any[];
@Input() hotTablesOnly: boolean = false;
@Input() memberBenefitsOnly: boolean = false;
numberOfTagsToDisplay: number = 3;
resultsPerPage: number = 5;
currentPage: number = 1;
constructor(private changeDetectorRef: ChangeDetectorRef) {
}
get filteredResults() {
return this.searchResults ?
this.searchResults.filter((r) => !((this.hotTablesOnly && !r.has_hot_table)
|| (this.memberBenefitsOnly && !r.has_member_benefit))) : [];
}
get pagedResults() {
return _.chain(this.filteredResults)
.drop(this.resultsPerPage * (this.currentPage - 1))
.take(this.resultsPerPage)
.value();
}
get totalPages(): number {
return Math.ceil(this.filteredResults.length / this.resultsPerPage);
}
getInitialTags(tagsArray: any[], count: number): any[] {
return _.take(tagsArray, count);
}
changePage(pageNumber) {
this.currentPage = pageNumber;
// Why is this necessary?
this.changeDetectorRef.detectChanges();
}
}
Upon calling changePage()
and updating this.currentPage
, the changes do not reflect in the HTML unless detectChanges()
is explicitly called.