Reputation: 281
Today i'm facing a new problem with services.
I'm trying to make an http service but when I try to store, in my service, the Observable object returned by http.get.map - my app crashs.
I wanted to achieve a "system" where the service loops to update datas and the components which subscribed to the observable update its data according to the service's data.
Here is the code :
afficheur.component.ts :
import { Component } from '@angular/core';
import {HardwareService} from "../../services/hardware.service";
@Component({
selector: 'afficheur',
templateUrl: 'app/components/hardware/afficheur.component.html'
})
export class AfficheurComponent{
public state: Boolean;
constructor(private service: HardwareService){
this.service
.getHardware()
.subscribe(data => (console.log(data), this.state = data.afficheur),
error => console.log(error),
() => console.log('Get etat afficheur complete'))
}
}
hardware.service.ts :
import { Injectable, OnInit } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Injectable()
export class HardwareService implements OnInit{
private apiUrl = 'http://10.72.23.11:5000'; // URL to web API
private ressources: Observable<any>;
constructor (private http: Http) {}
ngOnInit() {
this.loopupdate()
}
loopupdate(): void {
setInterval(() => {
this.update();
}, 5000);
}
update(): void {
this.ressources = this.http.get(this.apiUrl)
.map(this.extractData)
.catch(this.handleError);
}
getHardware(){
return this.ressources;
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
app.module.ts :
import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { ROUTING } from './app.routes';
import {HardwareService} from "./services/hardware.service";
import {AfficheurComponent} from "./components/hardware/afficheur.component";
import {HardwareListComponent} from "./views/hardwarelist/hardwarelist.component";
@NgModule({
imports: [ BrowserModule, ROUTING, HttpModule, FormsModule, HttpModule],
declarations: [
AppComponent,
AfficheurComponent,
HardwareListComponent
],
bootstrap: [ AppComponent ],
providers: [ HardwareService ]
})
export class AppModule { }
EDIT :
I got an error when i try to launch my app :
ERROR TypeError: Cannot read property 'subscribe' of undefined
I think it's related to the this.ressources initialization, any idea ?
EDIT 2 : In my service :
initializePolling(){
return IntervalObservable.create(5000)
.flatMap(() => {
return this.getHardware()
});
}
getHardware(): Observable<any> {
return this.http.get(this.apiUrl)
.map(this.extractData)
.catch(this.handleError);
}
How can i subscribe to this with my component ? I don't know what method i should call in my component to fetch datas without make multiple calls if i have multiple components.
Upvotes: 0
Views: 1555
Reputation: 3780
The problem is that ngOnInit()
, like the one in your Injectable class, is a Lifecycle hook which only works with Directives and Components. You should try calling this.loopUpdate()
from within the Injectable class' constructor. You can know more about this on another thread/question.
If you want to set an interval in fetching the data, do that in the component class, not in the service. In the service you should just have methods that return Observables (in your case) from calling http.get()...
. In that way you wouldn't have an undefined object returned and a more reusable service.
Also, here's another SO link for you to have look at.
Upvotes: 2