I am learning to use a reactive approach to my angular application. I'm able to add new items to an observable (array).
In my service, I am doing this to get all activities:
// activity.service.ts
private activityCreatedSubject = new Subject<IActivity>();
public activityCreatedAction$ = this.activityCreatedSubject.asObservable();
public storedActivities$: Observable<IActivity[]> = this.httpClient
.get<IActivity[]>(`${this.baseURL}/v1/activities`)
.pipe(
catchError((err) => {
return throwError(err);
})
);
...
public activities$ = merge(
this.storedActivities$,
this.activityCreatedAction$
).pipe(
tap((data) => console.log('activities$: ', data)),
scan(
(acc, value) =>
value instanceof Array ? [...value] : [...acc, value],
[] as IActivity[]
),
shareReplay(1)
);
storedActivities$ is my http request to get all activities that are saved to my database.
public storedActivities$: Observable<IActivity[]> = this.httpClient
.get<IActivity[]>(`${this.baseURL}/v1/activities`)
.pipe(
catchError((err) => {
return throwError(err);
})
);
Using | async in my template, i'm able to list all activities and add new ones. When I add a new activity, it is reflected in my UI immediately which is great!
Now I am trying to leverage what I've got to handle a delete request.
Here is what my remove method looks like in my service:
remove(activity: IActivity): Observable<any> {
const activityId = activity.id;
return this.httpClient
.delete<IActivity>(`${this.baseURL}/v1/activities/${activityId}`)
.pipe(
// TODO: filter activities to omit deleted.
// this.activities$.filter(a => a.id !== activityId)
catchError((err) => {
throw `Error deleting activity: ${err.error.message}`;
})
);
}
I'm able to successfully remove the activity from my database, but refreshing my ui is throwing me. I have tried different versions of filter without much luck.
I have tried making my activities$ into a BehaviorSubject, but does that take away from being reactive? I think I would have to implement some sort of getAllActivites method or something then call that from my component.
What is the ideal way to update the ui using a reactive approach? I think since activities$ is an observable, that is causing my problems, but I'm not sure how to get around that and still maintain a reactive flow.
EDIT
Here is how I am adding new activities. I am saving the activity to my database (Postgres) and updating the ui.
// activity.service.ts
create(activity: IActivity): Observable<IActivity> {
return this.httpClient
.post<IActivity>(`${this.baseURL}/v1/activities`, activity)
.pipe(
tap((response) => {
this.activityCreatedSubject.next(response);
}),
catchError((err) => {
throw `Error creating activity: ${err.error.message}`;
})
);
}
I'm able to update my list of activities by using merge and scan. It's probably painfully obvious I don't really quite grasp what I'm doing yet.