How to Update an Angular Signal that is set through RxJs stream in the service?

My Angular project has a service class called ProjectsService that handles project-related data. It manages a feed of tasks and lets me like them. The service has a signal called _like_res that shows the outcome of liking or disliking an activity and a signal called _projects_feed that shows the feed of activities.

I’m having trouble changing the _projects_feed signal after someone likes or dislikes something. I tried to change the signal in the tap operator in the _like_res$ observable, but it doesn’t work the way I thought it would. When a like is added or removed, I want the feed signal to show the new like status of the action.

export class ProjectsService {
  stream_service = inject(StreamService);
  profile_service = inject(ProfileService);
  user_service = inject(UserService);
  destroy_ref = inject(DestroyRef);

  profile_user$ = toObservable(this.profile_service.profile_user);

  like_event = new EventEmitter<{
    reaction: StreamReaction | null;
    activity: StreamActivityResponse | null;
  }>(); // activity to like

  projects_feed = signal<StreamActivityResponse[] | null>(null);
  private _projects_feed$ = this.profile_user$.pipe(
    switchMap((profile_user) => {
      let feedType="public_project";
      const current_user = this.user_service.current_user();
      if (!profile_user) {
        return EMPTY;
      }
      if (current_user && current_user.uid === profile_user.uid) {
        /* If the profile user is the current user, show their private projects */
        feedType="project";
      }
      return this.stream_service.readFeed(feedType, profile_user.uid).pipe(
        map((response: any) => {
          if (!response) {
            return EMPTY;
          }
          return response;
        }),
        tap((activities) => {
          console.log(activities, feedType);
          this.projects_feed.set(activities);
        })
      );
    }),
    tap((activities) => {
      console.log(activities);
    })
  );
  readonly _projects_feed = toSignal(this._projects_feed$, {
    initialValue: [],
  });

  like_res = signal<any>(null);
  private _like_res$ = this.like_event.pipe(
    debounceTime(1500),
    switchMap((event) => {
      console.log(event);
      const current_user = this.user_service.current_user();
      if (!current_user) {
        return EMPTY;
      }
      if (event.reaction) {
        return this.stream_service.deleteReaction(
          event.reaction
        ) as Observable<{
          success: boolean;
        }>;
      } else if (event.activity) {
        return this.stream_service.createReaction(
          current_user!.uid,
          'like',
          event.activity.actor,
          event.activity.id,
          'like'
        ) as Observable<{ success: boolean }>;
      } else {
        return EMPTY;
      }
    }),
    tap((res: { success: boolean }) => {
      console.log(res);
      if (res.success) {
        console.log('success');

        // HERE IS WHERE I NEED TO UPDATE THE PROJECTS_FEED SIGNAL TO REFLECT THE NEW LIKE ONCE THE LIKE IS CREATED OR DELETED
      }
    })
  );
  readonly _like_res = toSignal(this._like_res$, { initialValue: null });
}

Could someone please explain how to correctly change/refresh/reload the _projects_feed signal when a like is added or removed? Which RxJS operators or methods should I use to make this happen?

Appreciate it. Thanks in advance!

Since you’re using toSignal to convert an Observable to a signal

You need that observable to return a value and it will automatically update the signal.

So your tap should actually be a map.

Leave a Comment