Willy De Keyser
Willy De Keyser

Reputation: 111

Angular app - GroupBy for two observables from firestore database

I have 2 Obsevables kasboeklijst$ - RubriekLijst$ that I want to combine into KasboekMenu$.

kasboekLijst$: Observable<Kasboek[]>;

export interface Kasboek {
  id: string;
  kasboek_id: number;
  jaartal: number;
  omschrijving: string;
  datum: Timestamp;
  rubriek_id?: number;
  rubriek?: Rubriek;
  inkomsten: number;
  uitgaven: number;
}
rubriekLijst$: Observable<Rubriek[]>;

export interface Rubriek {
  id?: string;
  rubriek_id: number;
  rubriek: string;
  kasboek?: Kasboek[];
}

kasboekMenu$: Observable<KasboekMenu[]>;

export interface KasboekMenu {
  jaartal: number;
  rubriek?: RubriekMenu[];
}

export interface RubriekMenu {
  id?: number;
  rubriek?: string;
}

The result I expect:

 2017

    Vergaderingen
    Algemeen
    Opendeurdag
    Clubsouper
    Lidgeld
    ADSL
    Spaghetti avond 

2018

    Vergaderingen
    Algemeen
    Opendeurdag
    Clubsouper
    Lidgeld
    Nieuwjaar
    ADSL
    Spaghetti avond 

2019

    Vergaderingen
    Algemeen
    Clubsouper
    Lidgeld
    Nieuwjaar
    ADSL 

2020

    Vergaderingen
    Algemeen
    Lidgeld
    Nieuwjaar 

I extract the data in the obsevables from a Firestore database with this code:

this.rubriekLijst$ = this.angularFirestore
      .collection<Rubriek>('rubriek', rubriekQuery)
      .valueChanges();

this.kasboekLijst$ = this.angularFirestore
      .collection<Kasboek>('kasboek', kasboekQuery)
      .valueChanges();

My code works fine, my question is if I can simplify my code and is this the right way.

This is the code I use to sort and combine the obsevables:

let rubriekMenu: RubriekMenu;
    const kasboekMenu: KasboekMenu[] = [];
    this.kasboekMenu$ = zip(this.kasboekLijst$, this.rubriekLijst$).pipe(
      concatMap(([kasboeken, rubrieken]) => {
        rubriekLijst = rubrieken;
        return kasboeken;
      }),
      groupBy((groep: Kasboek) => groep.jaartal),
      mergeMap((groupedObservableData: GroupedObservable<number, Kasboek>) => {
        kasboekMenu.push({
          jaartal: groupedObservableData.key,
          rubriek: [],
        });
        kasboekMenu.sort((a: KasboekMenu, b: KasboekMenu) =>
          a.jaartal > b.jaartal ? 1 : b.jaartal > a.jaartal ? -1 : 0
        );
        return groupedObservableData.pipe(
          distinct((rubriekId) => rubriekId.rubriek_id),
          map((kasboek: Kasboek) => {
            const findRubriek = rubriekLijst.find(
              (rubriek) => rubriek.rubriek_id === kasboek.rubriek_id
            );
            rubriekMenu = {
              id: kasboek.rubriek_id,
              rubriek: findRubriek.rubriek,
            };
            const findKasboekMenu: KasboekMenu = kasboekMenu.find(
              (findMenu) => findMenu.jaartal === kasboek.jaartal
            );
            findKasboekMenu.rubriek.push(rubriekMenu);
            findKasboekMenu.rubriek.sort((a: RubriekMenu, b: RubriekMenu) =>
              a.id > b.id ? 1 : b.id > a.id ? -1 : 0
            );
            return kasboekMenu;
          })
        );
      })
    );

Upvotes: 2

Views: 64

Answers (1)

gso_gabriel
gso_gabriel

Reputation: 4660

I would say that your code is good right now and there isn't any specific thing that would improve it, as far as I can see. As it works perfectly - as you mentioned - your calls to Firestore are correct as well and it would be more about the way of sorting and combining your Observables. However, they seem to be well structured too.

In case you have still some doubts about it or want more examples of combining Observables, you can check the below pages for more information.

Upvotes: 1

Related Questions