Reputation: 1363
I am trying to create a data service that pulls data from my API every set number of seconds and returns two Observables of the two different data types that the API returns. I am new to Observables so any help would be greatly appreciated.
My API returns a two arrays of json objects (ex {'Data1':[array of data objects], 'Data2':[array of data objects]}
). Can I do something similar to this?
@Injectable()
export class DataService {
data: any = null;
dataType1: DataType1Model[] = [];
dataType2: DataType2Model[] = [];
service: Observable;
constructor(public http: Http) {}
start() {
this.service = Observable.interval(10000)
.flatMap(() => {
this.http.get('url')
.map(res => res.json())
.subscribe(data => {
this.data = data;
this.processData1(this.data.Data1);
this.processData2(this.data.Data2);
});
})
.subscribe()
}
stop(){
this.service.unsubscribe()
}
getData1() {
return this.dataType1
}
getData2() {
return this.dataType2
}
}
Then in my component I can just import the DataService and call data1 = DataService.getData1()
?
Will that call be an observable that will continue to update the data on the 10sec interval when the http request triggers? Again, I am new to observables, so sorry if this is totally wrong.
Upvotes: 3
Views: 2754
Reputation: 6432
Your Service module will be something like this
@Injectable()
export class DataService {
constructor(private http : Http) { }
// Uses http.get() to load a single JSON file
getData() : Observable<DataType1Model[]> {
return Observable.interval(10000)
.flatMap(this.http.get('url')
.map((res:Response) => res.json()));
}
}
And your Component should be like this-
@Component({
selector: 'Selector',
template: "Template",
providers:[
DataService,
]
})
export class DataComponent implements OnInit{
dataItem: DataType1Model[] ;
constructor(private _itemData:DataService ) { }
getData(){
this._itemData.getData()
.subscribe(
// the first argument is a function which runs on success
(data:DataType1Model[]) => {
this.dataItem = data;
},
// the second argument is a function which runs on error
err => console.error(err),
// the third argument is a function which runs on completion
() => console.log('done loading data')
);
}
ngOnInit() {
console.log('hello `Item` component');
this.getData();
}
stop(){
_itemData.getData()
.unsubscribe();
}
}
Call stop when you want to unsubscribe.
Upvotes: 3
Reputation: 657058
One problem with your approach is that when you call getData1()
or getData2()
there is no guarantee that data has already been received.
I also don't see where you call start()
.
I think calling subscribe(...)
on this.http.get(...)...
is a mistake. flatMap()
does the subscription by itself. It expects an Observable
not a Subscription
but when you call subscribe()
a Subscription
is what you get. To fix it replace the inner subscribe
to do
(and ensure the do
operator is imported) or move the code from subscribe
to the map
.
Upvotes: 1