I have this in my service:
import { Injectable, EventEmitter } from '@angular/core'
import { Response } from '@angular/http'
import { Observable, ReplaySubject } from 'rxjs/Rx';
import { AppSettings, HttpClient } from './shared';
import _ from "lodash";
@Injectable()
export class UserService {
private currentTruckTrailer: any;
private trucksTrailers: any;
public truckTrailerModified$: ReplaySubject<any>;
constructor(private http: HttpClient) {
this.truckTrailerModified$ = new ReplaySubject(1);
}
clearCache() {
this.currentTruckTrailer = null;
this.trucksTrailers = null;
}
login(username: string, password: string, clientID: number): Observable<any> {
return this.http.post(`${AppSettings.API_ENDPOINT}/User/Login`, { username: username, password: password, clientID: clientID }).map((response: Response) => {
return response.json();
});
}
getTrailersAndTrucks(): Observable<any> {
if (this.trucksTrailers) {
return Observable.of(this.trucksTrailers);
}
else {
return this.http.get(`${AppSettings.API_ENDPOINT}/User/GetTrailersAndTrucks`).map((response: Response) => {
if (response.status == 200) {
this.trucksTrailers = response.json();
return this.trucksTrailers;
}
else {
return "FAILURE";
}
});
}
}
saveTrailerAndTruck(truckID: string, trailerID: string): Observable<any> {
return this.http.post(`${AppSettings.API_ENDPOINT}/User/SaveTrailerAndTruck`, { truckID: truckID, trailerID: trailerID }).map((response: Response) => {
var truck = _.find(this.trucksTrailers.Trucks, function (item: any) {
return item.ID == truckID;
});
var trailer = _.find(this.trucksTrailers.Trailers, function (item: any) {
return item.ID == trailerID;
});
this.currentTruckTrailer = { Truck: truck, Trailer: trailer };
this.truckTrailerModified$.next(this.currentTruckTrailer);
return response.json();
});
}
getCurrentTruckAndTrailer() {
if (this.currentTruckTrailer) {
return Observable.of(this.currentTruckTrailer);
}
else {
return this.http.get(`${AppSettings.API_ENDPOINT}/User/GetCurrentTruckAndTrailer`).map((response: Response) => {
if (response.status == 200) {
this.currentTruckTrailer = response.json();
return this.currentTruckTrailer;
}
else {
return "FAILURE";
}
});
}
}
}
The above code works perfectly. What I want is when I modify the this.currentTruckTrailer
inside saveTrailerAndTruck
the subscribers should change their values automatically. At the moment I am using public ReplaySubject truckTrailerModified$: ReplaySubject<any>;
to broadcast the subscribe. Question is how do I turn the this.currentTruckTrailer
into Observable so listeners can directly subscribe upon it. What changes would I need to make inside saveTrailerAndTruck
and getCurrentTruckAndTrailer
.
You can use a BehaviorSubject
(documentation):
first of all, you have to initialize it:
currentTruckTrailer:BehaviorSubject<any> = new behaviorSubject<any>();
When you want to store the next value of your data, you can use next()
:
this.currentTruckTrailer.next({ Truck: truck, Trailer: trailer });
When you subscribe to this Observable
, you'll receive the last stored value if one exists, and your subscriber will get called everytime you call next()
.
EDIT: Here is an example implementation in your service. Since I do'nt know the context and how you want to use this service, this is probably not the best implementation you can get. The goal of this example is to show you how to implement it.
import {Injectable} from '@angular/core'
import {Response} from '@angular/http'
import {Observable, BehaviorSubject} from 'rxjs/Rx';
import {AppSettings, HttpClient} from './shared';
import _ from 'lodash';
@Injectable()
export class UserService {
private currentTruckTrailer: BehaviorSubject<any> = new BehaviorSubject<any>();
private trucksTrailers: BehaviorSubject<any[]> = new BehaviorSubject<any[]>();
constructor(private http: HttpClient) {
//First of all, we initialize the currentTruckTrailer with a value coming from http.
this.http.get(`${AppSettings.API_ENDPOINT}/User/GetCurrentTruckAndTrailer`)
.subscribe((response: Response) => {
this.currentTruckTrailer = new BehaviorSubject<any>(response.json());
});
//Same for truckTrailers.
this.http.get(`${AppSettings.API_ENDPOINT}/User/GetTrailersAndTrucks`)
.subscribe((response: Response) => {
this.trucksTrailers = new BehaviorSubject<any[]>(response.json());
});
}
login(username: string, password: string, clientID: number): Observable<any> {
return this.http.post(`${AppSettings.API_ENDPOINT}/User/Login`, {
username: username,
password: password,
clientID: clientID
}).map((response: Response) => {
return response.json();
});
}
getTrailersAndTrucks(): Observable<any> {
return this.trucksTrailers;
}
saveTrailerAndTruck(truckID: string, trailerID: string): Observable<any> {
return this.http.post(`${AppSettings.API_ENDPOINT}/User/SaveTrailerAndTruck`, {
truckID: truckID,
trailerID: trailerID
}).do(() => {
const truck = _.find(this.trucksTrailers.Trucks, function (item: any) {
return item.ID == truckID;
});
const trailer = _.find(this.trucksTrailers.Trailers, function (item: any) {
return item.ID == trailerID;
});
this.currentTruckTrailer.next({Truck: truck, Trailer: trailer});
}).map(response => {
return response.json();
});
}
getCurrentTruckAndTrailer(): Observable<any> {
return this.currentTruckTrailer;
}
}