管道异步 - 尝试diff [#object object]'时出错。只允许数组和迭代

时间:2018-01-22 22:25:46

标签: angular

我正在使用Tour Heroes教程:https://angular.io/tutorial/toh-pt6#search-by-name来创建我自己的搜索栏。然而,差异[对象对象]'错误出现了,虽然很多答案说我需要以数组形式转换对象,但是在教程中,它说异步管道为我处理了这个问题,所以我不必订阅。

提前谢谢!

Error message

提议 - search.component.html

    <input #searchBox id="search-box" (keyup)="search(searchBox.value)" />

      <ul class="search-result">
        <li *ngFor="let offer of offers$ | async" >
            {{offer.name}}
        </li>

提议 - search.component.ts

...
import { Offer } from '../model/offer';
import { OfferService } from '../offer.service';

@Component({
  selector: 'app-offer-search',
  templateUrl: './offer-search.component.html',
  styleUrls: ['./offer-search.component.css']
})
export class OfferSearchComponent implements OnInit {
  @Input('offerP') offerProperty: string;

  offers$: Observable<Offer[]>;
  private searchTerms = new Subject<string>();

  constructor(private offerService: OfferService) {}

  // Push a search term into the observable stream.
  search(term: string): void {
    this.searchTerms.next(term);
  }

  ngOnInit(): void {
    this.offers$ = this.searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term
      debounceTime(300),

      // ignore new term if same as previous term
      distinctUntilChanged(),

      // switch to new search observable each time the term changes
      switchMap((term: string) => this.offerService.searchOffersByProperty(term, this.offerProperty)),
    );
  }
}

offer.service.ts

...
  searchOffersByProperty(term: string, prpty: string): Observable<Offer[]> {
    if (!term.trim()) {
      // if not search term, return empty hero array.
      return of([]);
    }
    let searchURL = this.url + `/offers/?foodOfferer=${this.authService.credential.foodOfferer.id}&${prpty}=${term}`;
    return this.http.get<any>(searchURL, {
      headers: this.headers,
      responseType: 'json',
    }).pipe(catchError(this.handleError('searchOffersByProperty', '')));
  }

}

2 个答案:

答案 0 :(得分:0)

正如文档所述

  

AsyncPipe会自动订阅一个Observable,因此您不必在组件类中这样做。

这意味着您不必在组件中手动订阅。手动订阅看起来像

// ts
this.searchTerms.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap((term: string) => 
      this.offerService.searchOffersByProperty(term, this.offerProperty)),
  )
  .subscribe(offers => this.offers = offers);

// html
<li *ngFor="let offer of offers">
  {{offer.name}}
</li>

异步管道不进行数据转换。为此,您需要使用rxjs map方法将结果从api(当前是对象)转换为数组。

// ts
this.offers$ = this.searchTerms.pipe(
  debounceTime(300),
  distinctUntilChanged(),
  switchMap((term: string) => this.offerService.searchOffersByProperty(term, this.offerProperty)),
  map(results => {
      // do transformation here
      let resultsArray = ...;
      return resultsArray;
  })
);

答案 1 :(得分:0)

  1. 找到Offers$Observable<Object>,其中包含Offer[],而不是Observable<Offer[]>
  2. 如果您尝试访问异步变量,则发现需要? 所以代替:
  3. <li *ngFor="let offer of offers$ | async" >

    它是

    <li *ngFor="let offer of (offers$ | async)?.results" >