My code has a Subject
which, when new values are added triggers a HTTP request which returns an Observable
.
I want to process this data in two different ways (using the same data) and use the resulting Observables
stored in group
and times
as values to put in ngFor
using the async
pipe.
While this does work, the HTTP requests are sent multiple times - I only want them to be sent once for each subscription.
Below is a minimal example.
import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { ExampleService } from "../example.service";
import "rxjs/add/operator/switchMap";
@Component({
templateUrl: "./example.component.html",
styleUrls: ["./example.component.scss"]
})
export class ExampleComponent implements OnInit {
constructor(
private exampleService: ExampleService
) { }
ngOnInit() {
var selections = new Subject<string>();
var appointments = selections
// exampleService.getData returns an HTTP observable.
.switchMap(date => this.exampleService.getData(date));
var group = appointments
.map(data => this.process(data));
var times = appointments
.map(data => this.calculateTimes(data));
// Calling subscribe each time sends the HTTP request multiple
// times - I only want it to be send once for both of them: they
// can share the data!!
group.subscribe();
times.subscribe();
// selections.next(someData) is called periodically from some
// omitted code.
}
processExample(data: string[]) {
/*
* Some processing code.
*/
return data;
}
calculateTimes(data: string[]) {
/*
* Some processing code.
*/
return data;
}
}
What is the best way to achieve this?
You can use the share
operator to archive what you are looking for:
import 'rxjs/add/operator/share';
ngOnInit() {
var selections = new Subject<string>();
var appointments = selections
// exampleService.getData returns an HTTP observable.
.switchMap(date => this.exampleService.getData(date))
.share();
var group = appointments
.map(data => this.process(data));
var times = appointments
.map(data => this.calculateTimes(data));
// Calling subscribe each time sends the HTTP request multiple
// times - I only want it to be send once for both of them: they
// can share the data!!
group.subscribe();
times.subscribe();
// selections.next(someData) is called periodically from some
// omitted code.
}
Basically, the different observers
share the same source
among them.
More info about the operator here.