为什么在我的Angular代码中我会得到这个错误?错误:InvalidPipeArgument



我正在处理一个Angular项目,我遇到了以下问题。

基本上我有这个HomeComponent视图代码:

<div class="courses-panel">
<h3>All Courses</h3>
<mat-tab-group>
<mat-tab label="Beginners">
<courses-card-list [courses]="beginnerCourses$ | async"></courses-card-list>
</mat-tab>
<mat-tab label="Advanced">
<courses-card-list [courses]="advancedCourses$ | async"></courses-card-list>
</mat-tab>
</mat-tab-group>
</div>

下面是相关的TypeScript代码:

import {Component, OnInit} from '@angular/core';
import {Course, sortCoursesBySeqNo} from '../model/course';
import {interval, noop, Observable, of, throwError, timer} from 'rxjs';
import {catchError, delay, delayWhen, filter, finalize, map, retryWhen, shareReplay, tap} from 'rxjs/operators';
import {HttpClient} from '@angular/common/http';
import {MatDialog, MatDialogConfig} from '@angular/material/dialog';
import {CourseDialogComponent} from '../course-dialog/course-dialog.component';
import { CoursesService } from '../services/courses.service';

@Component({
selector: 'home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
beginnerCourses$: Observable<Course[]>;
advancedCourses$: Observable<Course[]>;

constructor(private coursesService: CoursesService) {
}
ngOnInit() {
const courses$ = this.coursesService.loadedAllCourses()
.pipe(
map(courses => courses.sort(sortCoursesBySeqNo))
)
this.beginnerCourses$ = courses$
.pipe(
map(courses => courses.filter(course => course.category == "BEGINNER"))
);
this.advancedCourses$ = courses$
.pipe(
map(courses => courses.filter(course => course.category == "ADVANCED"))
);

}
}

正如您在前面的组件初始化代码中看到的那样,首先我使用服务类的loadedAllCourses((方法检索Observable(它只是向API执行HTTP请求(,然后从这个Observable中,我创建了另外两个Observable,它们是beginerCurses$advancedCurses$,包含两种不同类型的课程,对检索到的课程Observable进行过滤。

在我的HomeComponent视图中,我声明了课程卡列表组件,该组件将只显示课程信息,类似于以下内容:

<courses-card-list [courses]="beginnerCourses$ | async"></courses-card-list>

和:

<courses-card-list [courses]="advancedCourses$ | async"></courses-card-list>

这是课程卡列表组件的视图代码:

<mat-card *ngFor="let course of (courses | async)" class="course-card mat-elevation-z10">
<mat-card-header>
<mat-card-title>{{course.description}}</mat-card-title>
</mat-card-header>
<img mat-card-image [src]="course.iconUrl">
<mat-card-content>
<p>{{course.longDescription}}</p>
</mat-card-content>
<mat-card-actions class="course-actions">
<button mat-button class="mat-raised-button mat-primary" [routerLink]="['/courses', course.id]">
VIEW COURSE
</button>
<button mat-button class="mat-raised-button mat-accent"
(click)="editCourse(course)">
EDIT
</button>
</mat-card-actions>
</mat-card>

这是相关的后端代码:

import { Component, OnInit, Input } from '@angular/core';
import { Course } from '../model/course';
import { MatDialogConfig, MatDialog } from '@angular/material/dialog';
import { CourseDialogComponent } from '../course-dialog/course-dialog.component';
@Component({
selector: 'courses-card-list',
templateUrl: './courses-card-list.component.html',
styleUrls: ['./courses-card-list.component.scss']
})
export class CoursesCardListComponent implements OnInit {
@Input()
courses: Course[] = [];

constructor(private dialog: MatDialog) { }
ngOnInit() {
}
editCourse(course: Course) {
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.width = "400px";
dialogConfig.data = course;
const dialogRef = this.dialog.open(CourseDialogComponent, dialogConfig);
}
}

问题是,在运行我的应用程序时,我获得了以下错误消息,该消息似乎与两个异步管道有关:

core.js:4081 ERROR Error: InvalidPipeArgument: '[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]' for pipe 'AsyncPipe'
at invalidPipeArgumentError (common.js:4148)
at AsyncPipe._selectStrategy (common.js:4250)
at AsyncPipe._subscribe (common.js:4240)
at AsyncPipe.transform (common.js:4228)
at Module.ɵɵpipeBind1 (core.js:24409)
at CoursesCardListComponent_Template (courses-card-list.component.html:1)
at executeTemplate (core.js:7329)
at refreshView (core.js:7198)
at refreshComponent (core.js:8335)
at refreshChildComponents (core.js:6991)
defaultErrorLogger @ core.js:4081
handleError @ core.js:4129
(anonymous) @ core.js:28062
invoke @ zone-evergreen.js:364
run @ zone-evergreen.js:123
runOutsideAngular @ core.js:27065
tick @ core.js:28062
(anonymous) @ core.js:27941
invoke @ zone-evergreen.js:364
onInvoke @ core.js:27138
invoke @ zone-evergreen.js:363
run @ zone-evergreen.js:123
run @ core.js:27020
next @ core.js:27940
schedulerFn @ core.js:24535
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:24525
checkStable @ core.js:27074
onLeave @ core.js:27184
onInvokeTask @ core.js:27132
invokeTask @ zone-evergreen.js:398
runTask @ zone-evergreen.js:167
invokeTask @ zone-evergreen.js:480
invokeTask @ zone-evergreen.js:1621
globalZoneAwareCallback @ zone-evergreen.js:1658
load (async)
customScheduleGlobal @ zone-evergreen.js:1773
scheduleTask @ zone-evergreen.js:385
onScheduleTask @ zone-evergreen.js:272
scheduleTask @ zone-evergreen.js:378
scheduleTask @ zone-evergreen.js:210
scheduleEventTask @ zone-evergreen.js:236
(anonymous) @ zone-evergreen.js:1928
(anonymous) @ http.js:1764
_trySubscribe @ Observable.js:42
subscribe @ Observable.js:28
subscribeToResult @ subscribeToResult.js:9
_innerSub @ mergeMap.js:59
_tryNext @ mergeMap.js:53
_next @ mergeMap.js:36
next @ Subscriber.js:49
(anonymous) @ subscribeToArray.js:3
_trySubscribe @ Observable.js:42
subscribe @ Observable.js:28
call @ mergeMap.js:21
subscribe @ Observable.js:23
call @ filter.js:13
subscribe @ Observable.js:23
call @ map.js:16
subscribe @ Observable.js:23
call @ map.js:16
subscribe @ Observable.js:23
shareReplayOperation @ shareReplay.js:28
subscribe @ Observable.js:23
call @ map.js:16
subscribe @ Observable.js:23
call @ map.js:16
subscribe @ Observable.js:23
createSubscription @ common.js:4160
_subscribe @ common.js:4241
transform @ common.js:4228
ɵɵpipeBind1 @ core.js:24409
HomeComponent_Template @ home.component.html:9
executeTemplate @ core.js:7329
refreshView @ core.js:7198
refreshComponent @ core.js:8335
refreshChildComponents @ core.js:6991
refreshView @ core.js:7248
refreshEmbeddedViews @ core.js:8289
refreshView @ core.js:7222
refreshComponent @ core.js:8335
refreshChildComponents @ core.js:6991
refreshView @ core.js:7248
renderComponentOrTemplate @ core.js:7312
tickRootContext @ core.js:8507
detectChangesInRootView @ core.js:8532
detectChanges @ core.js:9918
tick @ core.js:28052
(anonymous) @ core.js:27941
invoke @ zone-evergreen.js:364
onInvoke @ core.js:27138
invoke @ zone-evergreen.js:363
run @ zone-evergreen.js:123
run @ core.js:27020
next @ core.js:27940
schedulerFn @ core.js:24535
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:24525
checkStable @ core.js:27074
onHasTask @ core.js:27152
hasTask @ zone-evergreen.js:419
_updateTaskCount @ zone-evergreen.js:440
_updateTaskCount @ zone-evergreen.js:263
runTask @ zone-evergreen.js:184
drainMicroTaskQueue @ zone-evergreen.js:569
Promise.then (async)
scheduleMicroTask @ zone-evergreen.js:552
scheduleTask @ zone-evergreen.js:388
scheduleTask @ zone-evergreen.js:210
scheduleMicroTask @ zone-evergreen.js:230
scheduleResolveOrReject @ zone-evergreen.js:847
then @ zone-evergreen.js:979
bootstrapModule @ core.js:27726
./src/main.ts @ main.ts:13
__webpack_require__ @ bootstrap:78
0 @ main.ts:14
__webpack_require__ @ bootstrap:78
checkDeferredModules @ bootstrap:44
webpackJsonpCallback @ bootstrap:31
(anonymous) @ main.js:1
Show 72 more frames
core.js:4081 ERROR Error: InvalidPipeArgument: '[object Object],[object Object],[object Object]' for pipe 'AsyncPipe'
at invalidPipeArgumentError (common.js:4148)
at AsyncPipe._selectStrategy (common.js:4250)
at AsyncPipe._subscribe (common.js:4240)
at AsyncPipe.transform (common.js:4228)
at Module.ɵɵpipeBind1 (core.js:24409)
at CoursesCardListComponent_Template (courses-card-list.component.html:1)
at executeTemplate (core.js:7329)
at refreshView (core.js:7198)
at refreshComponent (core.js:8335)
at refreshChildComponents (core.js:6991)

怎么了?我错过了什么?如何解决此问题?

EDIT-1:*这是我的服务类代码:

@Injectable({
providedIn: 'root'
})
export class CoursesService {
constructor(private http:HttpClient) {}
loadedAllCourses(): Observable<Course[]> {
// The obsarvable return a JSON containing the "payload" property containing the array
//return this.http.get<Course[]>("/api/courses");
return this.http.get<Course[]>("/api/courses")
.pipe(
map(res => res["payload"]),
/* Keep the result of this HTTP request in memory avoiding that n async pipe or subscription
will cause n call to the API. Keep the result in memory and share between subsequence subscriber */
shareReplay()
);

}
}

正如您所看到的,loadedAllCourses((方法返回一个Observable;订阅";它通过async管道进入我的HomeComponent,以检索我试图传递给我的子组件的课程数组

<课程卡列表[课程]=";beginerCurses$|async"gt;

在这个调用中,您使用Async管道将可观察对象"拆包"为正则数组,并将其分配给课程卡列表的courses@Input((。

下一步,在课程卡片列表的HTML模板中,您将通过尝试解包再次将此正则数组视为可观察数组

最新更新