2

I need to get, from an observable, the first item in payload.result which type is avatar:

let result = this.fileService.getAvatarByUserId(2).pipe(
  map((payload: Payload<FileModel[]>) => payload.result),
  first((result: FileModel[]) => result.type == 'avatar')
);

But I get error that "is not assignable to type 'Observable'"

How to solve this?

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481

2 Answers2

1

You can do one of the following based on your needs...

filter + take(1)

this.fileService.getAvatarByUserId(2)
      .pipe(
        map((payload: Payload<FileModel[]>) => payload.result),
        flatMap(uploads => uploads), // Flattens the array
        filter(upload => upload.type === 'avatar'), // filters anything that's avatart
        take(1) // return only the first
    ).subscribe(
      console.log
    );

OR

first(predicate function) -> my preference

this.fileService.getAvatarByUserId(2)
      .pipe(
        map((payload: Payload<FileModel[]>) => payload.result),
        flatMap(uploads => uploads), // Flattens the array
        first(upload => upload.type === 'avatar') // returns the first positive match
    ).subscribe(
      console.log,
      console.log // this is to log an error if no match found when the subscription completes
    );

OR filter + first

this.fileService.getAvatarByUserId(2)
      .pipe(
        map((payload: Payload<FileModel[]>) => payload.result),
        flatMap(uploads => uploads), // Flattens the array
        filter(upload => upload.type === 'avatar'), // filters anything that's avatart
        first() // returns the first value
    ).subscribe(
      console.log,
      console.log // this is to log an error if no match found when the subscription completes
    );

first operator can notify if the condition was not met when the subscription completes by adding the error method to the subscription -> see the subscription for the last two options (probably why i like this the most...)

see this in action

edited to add more clarity for the first operator based on @Jonathan Stellwag comments (thank you!!!)

Dwaraka
  • 179
  • 8
  • Take and first is not the same. If you want an error in case a condition is not happening, first is the way to go. https://stackoverflow.com/questions/42345969/take1-vs-first – Jonathan Stellwag Jun 26 '20 at 07:15
0

You can use the filter and take operator.

let result = this.fileService.getFilesByUserId().pipe(
  filter(payload => payload.payload.result === 'avatar'),
  take(1)
);
Jonathan Stellwag
  • 3,843
  • 4
  • 25
  • 50
  • I need to apply the condition to each result and get the first that satisfies it and not to payload. I just updated my question to clarify it ... – Miguel Moura Jun 25 '20 at 21:37
  • @MiguelMoura I updated the answer. Please add further informations if it's still not your requirement. Best case szenario to understand your question would be to provide the exact source (observable emits + type) and what you expect as a result (when + type). – Jonathan Stellwag Jun 25 '20 at 22:46