angular - RxJS 6+ Tipul 'Observable' trebuie să aibă o metodă 'Symbol.iterator' care să returneze un iterator


Încercând să obțin un tablou filtrat de valori dintr-un observable, am primit următoarea eroare:

Tipul 'Observable' trebuie să aibă o metodă 'Symbol.iterator' care să returneze un iterator.

Cod :

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);
  }  
}

Dacă modific următorul

for (const orderItem of orderItems) {

către

for (const orderItem of [orderItems]) {

eroarea dispare, dar proprietatea orderNumber nu mai este recunoscută, iar IntelliSense spune:

Proprietatea 'orderNumber' nu există pe tipul 'Subscription'

Deci, cum pot să-l repar, vă rog?

Răspuns #1

mi se pare că cauți asta:

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

pentru ca acest lucru să funcționeze, va trebui să importați operatorul map:

import { map } from 'rxjs/operators';

Răspunsul #2

Recomand să separați modul în care vă conectați și căutați datele de logică de afaceri, astfel încât trecerea de la http la SignalR, de exemplu, să nu însemne schimbarea logicii de afaceri.

Creează un alt serviciu al cărui scop este doar să caute elemente folosind cereri HTTP, iar ItemsService-ul tău ar folosi acel serviciu pentru a căuta datele.

Nu trebuie să reconstruiești vectorul

@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);
    });
  });
}

}