0

I would like to return an Observable object from a Observable Array or objects. getTodoById() I tried to return by using pipe & map operators. Err messsages:

Type 'Observable<Todo | undefined>' is not assinable to type 'Observable'. Type 'Todo | undefined is not assignable to type 'Todo'. ts(2322)

I tried assigning "?" sign but it wasn't very useful. Maybe I did it wrong. This is my current code. I tried Observable<Todo | undefined> as a return type to getById() it showed the same error.

todo service:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, of, Subscription, pipe } from 'rxjs';
import { map } from 'rxjs/operators';
import { FilterBy } from '../models/filterBy.model';
import { SortBy } from '../models/sortBy.model';
import { Todo } from '../models/todo.model';

// this is BehaviorSubject - Can get .next
  private _todos$ = new BehaviorSubject<Todo[]>([])

  // this is an Observable - we CANNOT do .next.
  // It acts like a getter - You can list to it's changes
  // this makes a good separation!
  public todos$ = this._todos$.asObservable();

      public getById(id: string): Observable<Todo> {
    return this.todos$.pipe(map(todos=> todos.find(todo => todo._id === id)))
  }

todo model:

export interface Todo {
  _id: string,
  title:string,
  date:Date,
  isDone:boolean,
  importance:number
}
Uri Gross
  • 484
  • 1
  • 8
  • 20
  • Observable – MikeOne Nov 07 '21 at 12:36
  • Didn't help. to add : Observable as a return type to getVyId @MikeOne – Uri Gross Nov 07 '21 at 12:45
  • 2
    [`Array.prototype.find()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) returns the found item or `undefined`. Changing return type of function should fix. Were you getting a different error after the change? – BizzyBob Nov 07 '21 at 12:48
  • Could you try `.filter()` instead of map and find? – leila-m Nov 07 '21 at 12:53
  • @BizzyBob - I got the exact error after changing the return type ( Added undefined) – Uri Gross Nov 07 '21 at 14:00
  • @leila-m : did you mean : return this.todos$.pipe(filter(todo => todo._id === id)) – Uri Gross Nov 07 '21 at 14:10
  • @leila-m: now I am getting error: Type 'Observable' is not assignable to type 'Observable'. Type 'Todo[]' is missing the following properties from type 'Todo': _id, title, date, isDone, importance ts(2322) – Uri Gross Nov 07 '21 at 14:34
  • See if you can reproduce in [StackBlitz](https://stackblitz.com/fork/angular-ivy) – BizzyBob Nov 07 '21 at 17:58

3 Answers3

2

Have you tried to add filter operator

return this.todos$.pipe(
  map(todos=> todos.find(todo => todo._id === id)),
  filter(todo => !!todo)
)
Fateh Mohamed
  • 20,445
  • 5
  • 43
  • 52
1

You need to add undefined as a return type to getById because you are using find() and typescript is smart enough to know that your array will not always return a value.

  public getById(id: string): Observable<Todo | undefined> {
    return this.todos$.pipe(map(todos=> todos.find(todo => todo._id === id)))
  }

Or if you don't want to return undefined as a return value you can use casting as follows:

  public getById(id: string): Observable<Todo> {
    return this.todos$.pipe(map(todos=> todos.find(todo => todo._id === id))) as Observable<Todo>
  }

but I prefer the first solution

0

Thank you for your answers and trying to help. I decided to go for a simpler way which is:

  public getById(id: string): Todo | undefined{
    const todos = this._todos$.getValue();
    return todos.find(todo => todo._id === id);
  }
Uri Gross
  • 484
  • 1
  • 8
  • 20
  • 2
    "Important note from the author of RxJS 5: Using getValue() is a HUGE red flag you're doing something wrong. It's there as an escape hatch. Generally everything you do with RxJS should be declarative. getValue() is imperative. If you're using getValue(), there's a 99.9% chance you're doing something wrong or weird. – Ben Lesh Jul 21 '17 at 0:01 Link here: https://stackoverflow.com/questions/37089977/how-to-get-current-value-of-rxjs-subject-or-observable (see the answers) – DeborahK Nov 08 '21 at 22:46