Subject and Observable, how to delete item, filter() list and next()

12,666

i recommand you to create new attribute on your component, where you will last store state. (here understands array of songs).

Is always better conceptualize your code by, internal property who represent your state (or store) and another attribute who have the role to sync rest of your application (by observable / event).

Another tips is to strong type your code by model. Will be easier to debug and maintain.

Then you just have to update it according to your logic and next on your Subject

export interface SongModel {
        id: number;
        title: string;
        artiste: string;
    }

    export class ArtistComponent implements OnInit {
        private repertoire$ : Observable<SongModel[]>;
        private repertoireSubject: BehaviorSubject<SongModel[]>;
        //Array of song, should be same type than repertoireSubject.
        private songs: SongModel[];

        constructor(
            private route: ActivatedRoute,
            private service: ArtistService
        ) {

            //We push all actual references.
            this.getRepertoire().subscribe(
                songs => {
                    this.songs = songs;
                    this.repertoireSubject.next(this.songs);
                }
            );
        }

        ngOnInit() {
            //Because is suject of array, you should init by empty array.
            this.repertoireSubject = new BehaviorSubject<SongModel[]>([]);
            this.repertoire$ = this.repertoireSubject.asObservable();
        }


        getRepertoire() {
            return this.route.paramMap
                .switchMap((params: ParamMap) =>
                this.service.fetchRepertoire(params.get('id')));
        }

        //THIS IS WHERE I'M HAVING TROUBLE
        delete(id: number): void {
            // Update your array referencial.
            this.songs = this.songs.filter(songs => songs.id !== id);
            // Notify rest of your application.
            this.repertoireSubject.next(this.songs);
        }
    }
Share:
12,666
Jason Svendstorp
Author by

Jason Svendstorp

Updated on June 05, 2022

Comments

  • Jason Svendstorp
    Jason Svendstorp almost 2 years

    I have a list of songs setup with Subject and Observable (shown with | async in view), and now I want to delete a song off the list, do some filter() and call next() on the Subject.

    How and where do I filter? Right now I am doing getValue() on Subject and passing that to next() on, well, Subject. This just seems wrong and circularish.

    I also tried subscribing to the Subject and getting the data that way, filtering it and calling next() inside subscribe(), but I got a RangeError.

    I could filter the Observable by storing all deleted id's. The Subject's list then becomes out of sync by having deleted songs on there and also every observer would have to have the deleted-id's-list which seems ludicrous. I'm rapidly growing old and mental. Please help me internet :(

    export class ArtistComponent implements OnInit {
      private repertoire$;
      private repertoireSubject;
      constructor(
        private route: ActivatedRoute,
        private service: ArtistService
      ) {
        this.getRepertoire().subscribe(
          songs => this.repertoireSubject.next(songs)
        );
      }
    
      getRepertoire() {
        return this.route.paramMap
          .switchMap((params: ParamMap) =>
          this.service.fetchRepertoire(params.get('id')));
      }
    
      //THIS IS WHERE I'M HAVING TROUBLE
      delete(id): void {
        this.repertoireSubject.next(
          this.repertoireSubject.getValue().filter(song => (song.id !== id))
        );
        // TODO remove song from repertoire API
      }
    
      ngOnInit() {
        this.repertoireSubject = new BehaviorSubject<any>(null);
        this.repertoire$ = this.repertoireSubject.asObservable();
      }
    
    }