I am trying to update my view after a websocket event returns updated data.
I injected a service into my app and call getData() method on the service. This method emits a socket.io event to my NodeJS server which in turn performs an external api call and parses some data. The NodeJS server then emits a success event with the new data that I listen for in my service. When the success event is returned I then update my property on the service that is referenced in my view.
However no matter what I try I cannot get the data to show once the property is updated.
I have searched for a few days now and all I find are blog posts that say this change should be seamless, or that I need to incorporate zone.js somehow, or to try the same logic using forms (however im trying to do this without user interaction). Nothing seems to work for me and I am getting a bit frustrated.
For example:
Lets say I receive an array of strings that I want to create an unsorted list with.
app.ts
import {Component, View, bootstrap, NgFor} from 'angular2/angular2';
import {MyService} from 'js/services/MyService';
// Annotation section
@Component({
selector: 'my-app',
viewInjector: [MyService]
})
@View({
templateUrl: 'templates/my-app.tpl.html',
directives: [NgFor]
})
class MyComponent {
mySvc:MyService;
constructor(mySvc:MyService) {
this.mySvc = mySvc;
this.mySvc.getData();
}
}
bootstrap(MyComponent, [MyService]);
MyService.ts
let socket = io();
export class MyService {
someList:Array<string>;
constructor() {
this.initListeners();
}
getData() {
socket.emit('myevent', {value: 'someValue'});
}
initListeners() {
socket.on('success', (data) => {
self.someList = data;
});
}
}
my-app.tpl.html
<div>
<h2>My List</h2>
<ul>
<li *ng-for="#item of mySvc.myList">Item: {{item}}</li>
</ul>
</div>
Interesting enough, I have found that If I incorporate a timeout within my component that updates some arbitrary property that I set on the view after the someList property is updated from the success callback then both property values are updated correctly at the same time.
For instance:
new app.ts
import {Component, View, bootstrap, NgFor} from 'angular2/angular2';
import {MyService} from 'js/services/MyService';
// Annotation section
@Component({
selector: 'my-app',
viewInjector: [MyService]
})
@View({
templateUrl: 'templates/my-app.tpl.html',
directives: [NgFor]
})
class MyComponent {
mySvc:MyService;
num:Number;
constructor(mySvc:MyService) {
this.mySvc = mySvc;
this.mySvc.getData();
setTimeout(() => this.updateNum(), 5000);
}
updateNum() {
this.num = 123456;
}
}
bootstrap(MyComponent, [MyService]);
new my-app.tpl.html
<div>
<h2>My List {{num}}</h2>
<ul>
<li *ng-for="#item of mySvc.myList">Item: {{item}}</li>
</ul>
</div>
So how should I go about getting angular2 to recognize that the data has changed after the 'success' event without updating some other property?
Is there something I am missing with the use of the NgFor directive?
See Question&Answers more detail:
os