I'm not sure what your goal is. To only update the data in the view when the button is clicked, even when the service provided fresh data in the meantime, or add some entirely new details object on button click to the stream, but the view should continously update the details regardles of them coming from the service or the button click. Assuming the second case for now:
To control the flow of a stream, that is to be able to add to a stream, you can use a Subject
.
Local Subject
Assuming you don't want to touch the _service
logic, and only need the refreshed value inside your component, but still get the input from its getDetails()
observable: You can subscribe to the service in your ngOnInit
, handing the result to your local Subject
and also handing the refreshed value in your refreshData()
method. Assuming the type of the details to be Details
we get:
private details$: Subject<Details>;
constructor(private _service: Service) {}
ngOnInit(): void {
this._service.getDetails().subscribe(updateDetails => this.details$.next(updateDetails));
}
ngOnDestroy(): void {
this.details$.complete();
}
public refreshData(): void {
this.details$.next(new Details());
}
Service Subject
If you want to keep the update not only locally but send it to the service, you have to adjust the services logic to handle an update to the details. That means turning the service observable into a Subject
. Usually you don't want to expose the services Subjects directly but only the observable side of the subject and handle update requests in a method. That means in your service:
private _detailsSource$: Subject<Details> = new Subject<Details>();
private _details$: Observable<Details> = this._detailsSource$.asObservable();
public getDetails(): Observable<Details> {
return this._details$;
}
public updateDetails(update: Details): void {
// you can add some check logic if the update is valid here
this._detailsSource$.next(update);
}
And in your component you just need to adjust your refresh method:
refreshData(): void {
this._service.updateDetails(new Details());
}
You can also skip the getDetails
method in your service and just expose the details observable directly by making it public:
private _detailsSource$: Subject<Details> = new Subject<Details>();
public details$: Observable<Details> = this._detailsSource$.asObservable();