[Fixed] Angular – How to put one single object<T> in a BehaviorSubject<T[]>

Issue

I have a data table populated by a BehaviorSubject<Sequence[]>, here’s how it works:

//sequencesService

findSequences(pageIndex: number, pageSize: number, rrc: string, datiForm: FormComponent): Observable<PaginatedResult>{
    return this.http.get<PaginatedResult>('https://bgpie.net/api/rrc/' + rrc + '/sequence', { params});
    }

//dataSource
export class SequencesDataSource implements DataSource<Sequence> {

    private sequencesSubject = new BehaviorSubject<Sequence[]>([]);

    private loadingSubject = new BehaviorSubject<boolean>(false);

    public loading$ = this.loadingSubject.asObservable();

    public length = new BehaviorSubject<number>(0);

loadSequences(pageIndex: number,
                  pageSize: number,
                  rrc: string,
                  datiForm: FormComponent) {

        this.loadingSubject.next(true);

        this.sequencesService.findSequences(pageIndex, pageSize, rrc, datiForm).pipe(
                finalize(() => this.loadingSubject.next(false)),
                tap(x => this.length.next(x.total))
            )
            .subscribe((sequences: PaginatedResult) => {
            this.sequencesSubject.next(sequences.items);
        });}
    }

//PaginatedResult
export interface PaginatedResult{
  readonly items: Sequence[];
  readonly total: number;
}

I would like to be able to filter the table using the sequence Id as a criteria. This means that only one sequence would have to be shown. While the method findSequences calls for an API containing an array of sequences, the method below calls for an API with a single sequence, as it should be:

getSequence(id: string): Observable<Sequence> {
        return this.http.get<Sequence>('https://bgpie.net/api/sequence/' + id);
    }

The problem is that I can’t use an observable of type Sequence to populate a BehaviorSubject<Sequence[]>.
I tried returning an observable of type Sequence[] (like in the code below) and then subscribing to it but it doesn’t work.

//sequencesService
getSequenceFilter(id: string): Observable<Sequence[]> {
        return this.http.get<Sequence[]>('https://bgpie.net/api/sequence/' + id);
    }

//dataSource
loadSequence(datiForm: FormComponent){
        this.loadingSubject.next(true);

        this.sequencesService.getSequenceFilter(datiForm.sequenceId).pipe(
            finalize(() => this.loadingSubject.next(false)),
            finalize(() => this.length.next(1))
        )
        .subscribe((sequence: Sequence[]) => this.sequencesSubject.next(sequence))

Solution

Do the following simple changes:

  1. Have getSequence(id: string) return Observable<Sequence>
  2. In loadSequence method change to .pipe(......., map(sequence => [sequence]), tap(sequence => this.sequencesSubject.next(sequence))).subscribe()

Leave a Reply

(*) Required, Your email will not be published