I have a component in my project that calls a service to retrieve some (locally-stored) JSON, which is mapped to an array of objects and returned to the component to be displayed. The problem I am having is that the bindings in the view don't seem to update the first time I call the service, but do update the second time I call the service.
The component template:
@Component({
selector: 'list-component',
template: `
<button type="button" (click)="getListItems()">Get List</button>
<div>
<table>
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
Job Title
</th>
</tr>
<tr *ngFor="let employee of _employees">
<td>
{{employee.id}}
</td>
<td>
{{employee.name}}
</td>
<td>
{{employee.jobTitle}}
</td>
</tr>
</table>
</div>
`,
changeDetection: ChangeDetectionStrategy.Default
})
The component controller class:
export class ListComponent {
_employees: Employee[];
constructor(
private employeeService: EmployeeService
) {
}
getListItems() {
this.employeeService.loadEmployees().subscribe(res => {
this._employees = res;
});
}
}
And the service:
@Injectable()
export class EmployeeService {
constructor(
private http: Http
) { }
loadEmployees(): Observable<Employee[]> {
return this.http.get('employees.json')
.map(res => <Employee[]>res.json().Employees);
}
}
Things I've tried:
ChangeDetectionStrategy
to OnPush
_employees
property an observable, populating it with this._employees = Observable<Employee[]>
and using the async pipe on the ngFor statement: *ngFor="let employees of _employees | async"
- same situation, only populates on second button clickCan anyone spot anything wrong with my code, or are aware of any issues with RC6 that could lead to such behaviour?
So Angular has two functions each specializing on a particular node definition and calls them at different stages when checking a component: Both these functions are executed each time Angular performs change detection for a component and the parameters to the function are supplied by the change detection mechanism.
Below I had detailly elaborated in a comprehensive way on how to set default values for Angular 2 component. First code the .html file with respect to requirements. Then include the default property in the child component. Now initialize the property with a default value using the @Input () decorator.
You don’t have to do anything else for the span, but for the b-comp you need to indicate that it receives textContent property: Now, whenever the AText property changes on the A component Angular will automatically update the property textContent on B component and span. It will also call ngOnChanges lifecycle hook for the child component.
As you probably know Angular provides template syntax for property bindings - . This syntax is generic so it can be applied for both child components and native DOM elements. So if you want to pass some data to the child b-comp and span from the parent A component you do it like this in the component’s template:
I had same issue. Still didn't get any solid solution. Using detectChanges
works. Below is the workaround but please note that this is not the perfect solution
export class ListComponent {
_employees: Employee[];
constructor(
private employeeService: EmployeeService, private chRef: ChangeDetectorRef
) {
}
getListItems() {
this.employeeService.loadEmployees().subscribe(res => {
this._employees = res;
this.chRef.detectChanges()
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With