Home > Net >  Angular returning observable object from Objservable Array of objects:
Angular returning observable object from Objservable Array of objects:

Time:11-08

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
}

CodePudding user response:

Have you tried to add filter operator

return this.todos$.pipe(
  map(todos=> todos.find(todo => todo._id === id)),
  filter(todo => !!todo)
)

CodePudding user response:

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

  • Related