1

I have a bit of a complicated observable in Angular (courtesy of using Akita, I cannot change this), it's a |'ed Observable of either an array of Dinosaur objects, or a single Dinosaur object, or undefined:

import { QueryEntity } from "@datorama/akita";

export class DinosaurQuery extends QueryEntity<DinosaurState, Dinosaur> {
  activeDinosaurs$ = this.selectActive(); // Type: Observable<Dinosaur[]> | Observable<Dinosaur | undefined>

  constructor(protected store: DinosaursStore) {
    super(store);
  }
}

What I want to get from this, as an observable, is either the single object, or the first object in the array in case it is an array. Or undefined, if there is none.

export class DinosaurSelection {
    // I want singleSelectedDinosaur$ to be of type: Observable<Dinosaur | undefined>
    singleSelectedDinosaur$ = this.dinosaurQuery.activeDinosaurs$.pipe(???);

    constructor(protected dinosaurQuery: DinosaurQuery) {}

}

I presume there must be some pipe that does this, but I can't find something appropriate that can act on the | of an object and an array of that object at the same time. (Or maybe it can't be done with a pipe but in another way, that's also fine.)

Yellow
  • 3,955
  • 6
  • 45
  • 74

1 Answers1

3

just use "pipe(map)" to transform if is array

singleSelectedDinosaur$ = this.dinosaurQuery.activeDinosaurs$.pipe(
    map((res:any)=>{
       if (res && Array.isArray(res)) //if res and is array
          return res[0]   //return the first element
       return res;      //else resut res
    }
));
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • Thanks, this is indeed what I'm looking for, but it's giving me an error: `error TS2554: Expected 0 arguments, but got 1.` Any idea why that would be? – Yellow Sep 06 '20 at 20:27
  • I can't see where the error there are, try `(res:any|any[])` – Eliseo Sep 07 '20 at 05:59
  • Still gives the same error... but oddly it does actually run correctly, so might be some compiler error level setting - I've marked the answer as Accepted. Could it be I'm missing some imports to have this work correctly? I have: `import { isArray } from "util"; import { map } from "rxjs/operators";` – Yellow Sep 07 '20 at 11:49
  • isArray is JavaScript: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/isArray, so, you **has not need** import anything, "map" is an operator of 'rxjs/operators', so **you must** import map from 'rxjs/operators' – Eliseo Sep 07 '20 at 12:11
  • The remaining error turned out to be unrelated to this ticket. For completeness' sake it was a result of an issue described here: https://github.com/datorama/akita/issues/184 But can be ignored for the purposes of this question. – Yellow Sep 11 '20 at 11:02