I'm changing a list property in my app component when an AJAX call has returned but my view is not updating accordingly.
Here is the component:
import {Component} from '@angular/core';
import {ValuesService} from "./services/ValuesService";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ValuesService]
})
export class AppComponent {
values: string[];
constructor(private valuesService: ValuesService) {
this.values = ['1', '2'];
}
onClick() {
this.valuesService.getValues().subscribe(this.onValues)
}
onValues(values: string[]) {
for (let value of values) {
console.log(value);
}
this.values = values // this should change the view
}
}
view:
<button (click)="onClick()">Hit Me</button>
<div *ngFor="let value of values">
<h3>{{value}}</h3>
</div>
When I click the button, I do see in the console:
received value1,value2,value3
app.component.ts:27 value1
app.component.ts:27 value2
app.component.ts:27 value3
However, the view doesn't change.
What could be causing this issue? Here are my dependencies in package.json:
"dependencies": {
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"core-js": "^2.4.1",
"rxjs": "^5.1.0",
"zone.js": "^0.8.4"
},
EDIT:
The fix is to change:
this.valuesService.getValues().subscribe(this.onValues)
to
this.valuesService.getValues().subscribe(values => this.onValues(values))
looks like this.values = values line inside this.onValues wasn't evaluating "this" to the app, but to the function itself. It's something to do with scoping.
Just as a guess ... it could be the this. The normal scope for this is at the function level. So it may not be referencing the class property. I normally use an arrow function that gets around this issue. Something like this:
this.productService.getProducts()
.subscribe(products => this.products = products,
error => this.errorMessage = <any>error);
Since it is in an arrow function, the this here is referencing the class property.
Check this out for more information: https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript