RxJS 6+ Type 'Observable' must have a 'Symbol.iterator' method that returns an iterator

Viewed 1465

Trying to get a filtered array of values from an observable I got the following error:

Type 'Observable' must have a 'Symbol.iterator' method that returns an iterator.

Code:

export class ItemsService {

  orderItems: OrderItem[] = [];
  orderItemsUrl = 'http://localhost:5000/order-items/';

  getOrderItemsFromHttp(selectedOrderNumber): Observable<OrderItem[]> {
    const tempArr = [];
      const orderItems = of (this.http.get<OrderItem[]>(`${this.orderItemsUrl}`)
      .subscribe(res => {
            this.orderItems = res;
      }) );

    for (const orderItem of orderItems) {                        <--- Error here
        if (orderItem.orderNumber === selectedOrderNumber) {
          tempArr.push(orderItem);
        }
    }
    return of(tempArr);
  }  
}

If I modify the following

for (const orderItem of orderItems) {

to

for (const orderItem of [orderItems]) {

error disappears but the property orderNumber is no more recignized, and the intellisens says:

Property 'orderNumber' does not exist on type 'Subscription'

So how can I fix it, please ?

2 Answers

it seems to me you're looking for this:

  getOrderItemsFromHttp(selectedOrderNumber): Observable<OrderItem[]> {
    return this.http.get<OrderItem[]>(`${this.orderItemsUrl}`).pipe(
      map(orderItems => orderItems.filter(oi => oi.orderNuber === selectedOrderNumber))
    );
  }  

for this to work you'll need to import the map operator:

import { map } from 'rxjs/operators';

I recommend separating the way you connect and look for business logic data, so that changing from http to SignalR for example does not mean changing your business logic.

Create another service that its task is only to search for elements using http request, your ItemsService would use that service to search the data.

You don't need to rebuild the array

@Injectable ({
   providedIn: 'root'
})
export class RestService {
config: Config; // Your URLs
   getItems () {
     return this.http.get <OrderItem []> (this.config.itemURL, {note: 'response'});
   }
}

@Injectable ()
export class ItemsService {

  orderItems: OrderItem [];

constructor (private restService: RestService) {
}

getItems () {
   return new Observable ((observer) => {
    restService.getItems (). subscribe ((items) => {
      observer.next (items);
    });
  });
}

}

Related