Tony Krøger Tony Krøger - 1 month ago 36
AngularJS Question

Angular2 http at an interval

I am quite new to angular and rxjs.
I am trying to create an angular2 app that gets some data from staticly served text file(Locally on server), which I would like to retrieve and map to Datamodel using Angular2's http provider and rxjs's map at a fixed time

interval(5000)
. To reflect any changes to the served txt file.

With rxjs 4.x I know you could use
Observable.interval(5000)
to do the job, but it does not seem to exist in rxjs 5.
My workaround currently refresh the whole application using
<meta http-equiv="refresh" content="5" >
Which reloads the whole page, and thus reloads the data.

So what I would really like is some way to do this working with observables, maybe to check if any changes have happened. or just to reload the data anew.

Any help or other/better way will be very much appreciated.

What I have so far:

@Injectable()
export class DataService {

constructor(private http:Http){}

getData(url) {
return this.http.get(url)
.map(res => {
return res.text();
})
.map(res => {
return res.split("\n");
})
.map(res => {
var dataModels: DataModel[] = [];
res.forEach(str => {
var s = str.split(",");
if(s[0] !== "") {
dataModels.push(new DataModel(s[0], parseInt(s[1]), parseInt(s[2])));
}
});
return dataModels;
})
}
}

@Component({
selector: 'my-app',
template: `Some html to display the data`,
providers: [DataService],
export class AppComponent {

data:DataModel[];

constructor(dataService:DataService) {}

ngOnInit() {
this.dataService.getData('url').subscribe(
res => {
this.data= res;

},
err => console.log(err),
() => console.log("Data received")
);
}
}


Dependencies: package.json

"dependencies": {
"angular2": "^2.0.0-beta.3",
"bootstrap": "^4.0.0-alpha.2",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.13",
"jquery": "^2.2.0",
"reflect-metadata": "^0.1.2",
"rxjs": "^5.0.0-beta.0",
"systemjs": "^0.19.20",
"zone.js": "^0.5.11"
},
"devDependencies": {
"typescript": "^1.7.5"
}


index.html imports:

<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>

<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>

Answer

You can use the interval method of Observable within Angular2.

import {Component,Input} from 'angular2/core';
import {Observable} from 'rxjs/Rx';

@Component({
  selector: 'my-app',
  template: `
    <div>
      {{message}}
    </div>
  `
})
export class AppComponent {
  constructor() {
    Observable.interval(500)
          .take(10).map((x) => x+1)
          .subscribe((x) => {
            this.message = x;
          }):
  }
}

Here is the corresponding plunkr describing this: https://plnkr.co/edit/pVMEbbGSzMwSBS4XEXJI?p=preview.

Based on this, you can plug your HTTP request:

initializePolling() {
  return Observable
     .interval(60000)
     .flatMap(() => {
       return this.dataService.getData('url'));
     });
}