0

I needed a custom PUT request related to my entity in ngrx/data, I would like to show it as I am not certain it is accurate... Say a I have a movie library and I can add tags to movies with PUT request.

My data service:

export class MovieDataService extends DefaultDataService<typeof Movie> {
  constructor(http: HttpClient, httpUrlGenerator: MovieHttpUrlGenerator, logger: Logger) {
    super('Movie', http, httpUrlGenerator);
    logger.log('Created custom Movie EntityDataService');
  }

  // CUSTOM METHODS APART FROM AUTO-CRETED BY COLLECTION SERVICE 
  // Further handled in collection service
  addTagToMovie(movieId: number, tagId: number) {
    return this.execute(
      'PUT', 
      `https://external-api.com/movie/${movieId}/add_tag/${tagId}/`,
    )
  }

}

Collection-service

 constructor(
    EntityCollectionServiceFactory: EntityCollectionServiceFactory,
    private movieDataService: movieDataService,
  ) {
    this.movieCollectionService = EntityCollectionServiceFactory.create<typeof Movie>('Movie');
  }

  getMovies() { this.movieCollectionService.getAll(); }

  addTagToMovie(movieId: number, tagId: number) {
    if (movieId && tagId) {
      this.movieCollectionService.setLoaded(false)
      this.movieCollectionService.setLoading(true)

      this.movieDataService.addTagToMovie(movieId, tagId).pipe(
        tap((updatedMovie: typeof Movie) => {
          this.movieCollectionService.updateOneInCache(updatedMovie)
          this.movieCollectionService.setLoading(false)
          this.movieCollectionService.setLoaded(true)
        })
      ).subscribe()
    }

  }

Is this an appropriate way to achieve this? Also, will the subscribe on addTagToMovie cause a memory leak? Without it, it does not trigger, other collection services methods need no subscribing (for instance getAll()) is it possible to implement it withou subscriibng as well?

I tried the described above.

grx00
  • 19
  • 3

1 Answers1

0

My understanding is that the subscribe need not happen on the service, instead just return an observable on the service, which will get subscribed on the component.

Collection-service

 constructor(
    EntityCollectionServiceFactory: EntityCollectionServiceFactory,
    private movieDataService: movieDataService,
  ) {
    this.movieCollectionService = EntityCollectionServiceFactory.create<typeof Movie>('Movie');
  }

  getMovies() { this.movieCollectionService.getAll(); }

  addTagToMovie(movieId: number, tagId: number) {
    let output$ = of([]);
    if (movieId && tagId) {
      this.movieCollectionService.setLoaded(false)
      this.movieCollectionService.setLoading(true)

      output$ = this.movieDataService.addTagToMovie(movieId, tagId).pipe(
        tap((updatedMovie: typeof Movie) => {
          this.movieCollectionService.updateOneInCache(updatedMovie)
          this.movieCollectionService.setLoading(false)
          this.movieCollectionService.setLoaded(true)
        })
      )
    }
    return output$;
  }

In the component you can do

private subscription: Subscription = new Subscription();

ngOnInit() {
    this.subscription.add(
        this.collectionService.addTagToMovie(1,2).subscribe()
    );
}

ngOnDestroy() {
    this.subscription.unsubscribe();
}
Naren Murali
  • 19,250
  • 3
  • 27
  • 54