In my Angular 2 and Typescript project, I am utilizing rxjs
. The goal is to share a common web-resource (referred to as a "project" in the app) among multiple components. To achieve this, I implemented a service that provides an observable to be shared by all clients:
/**
* Provided to clients for subscription.
*/
private _observable : Observable<Project>;
/**
* Used for emitting events to clients.
*/
private _observer : Observer<Project>;
constructor(private _http: Http) {
// Create the observable and observer once to be shared with all subscribers.
this._observable = Observable.create( (obs : Observer<Project>) => {
this._observer = obs;
});
}
Clients can simply reference the _observable
and subscribe to it.
/**
* Returns an observable always pointing to the active project.
*/
get ActiveProject() : Observable<Project> {
return (this._observable);
}
When a component wants to load a specific project, it triggers the following method:
/**
* @param id The id of the project to set for all subscribers
*/
setActiveProject(id : string) {
// Prevents project changes during ongoing requests
if (this._httpRequest) {
throw { "err" : "HTTP request in progress" };
}
this._httpRequest = this._http.get('/api/project/' + id)
.catch(this.handleError)
.map(res => new Project(res.json()));
this._httpRequest.subscribe(res => {
// Cache the project
this._cachedProject = res;
// Indicates no more requests are pending
this._httpRequest = null;
// Notifies subscribers about the change
this._observer.next(this._cachedProject)
console.log("Retrieved project");
});
}
This code performs an HTTP request, transforms the JSON data into an instance, and uses this._observer.next()
to inform all subscribers about the update.
If a subscription occurs after the initial HTTP request, the subscriber won't receive any data until a new request is sent. I've learned about a caching or replay mechanism in rxjs
that addresses this issue, but I'm unsure how to implement it.
tl;dr: How can I ensure that a call to subscribe
on the observer initially receives the most recent value?
Extra question: Did removing the observer from the observable in the constructor essentially create a subject?