我有一个Angular应用程序,它将firebase uid发布到我的服务器,然后返回一个响应,其中包含要在数据表中显示的对象数组。
当我从默认页面转到数据表时,它可以正常工作,但是当我重新加载应用程序时,它中断了,我得到了Error trying to diff '[object Object]'. Only arrays and iterables are allowed
。
我认为该错误是因为它返回错误消息,并且无法在表中显示。
我认为问题在于,当我重新加载页面时,它没有获取用户uid,因此我发送给服务器的参数是未定义的,因此它将返回该错误。
所以,我的问题是在向服务器发送请求之前,如何在重新加载数据表组件时获取用户uid。
服务:
private user: Observable<firebase.User>;
public userDetails: firebase.User = null;
uid: any;
constructor(private http: HttpClient,
private authFirebase : AngularFireAuth) {
this.user = authFirebase.authState;
this.user.subscribe(
(user) => {
if (user) {
this.userDetails = user;
console.log(this.userDetails.email);
this.uid = this.userDetails.uid;
}
else {
this.userDetails = null;
}
}
);
}
getFullRegistryUniversity(): Observable<DegreeDetails[]> {
console.log(`serviceuid: ${this.uid}`);
let uidString = {
"uid" : this.uid
}
return this.http.post<DegreeDetails[]>(this.serviceUrl, uidString)
}
组件:
export class GraduateComponent implements OnInit {
dataSource = new UserDataSource(this.registryService);
displayedColumns = ['graduateRut', 'major', 'university', 'gradYear'];
constructor(private registryService: RegistryService) { }
ngOnInit() {}
}
export class UserDataSource extends DataSource<any> {
constructor(private registryService: RegistryService) {
super();
}
connect(): Observable<DegreeDetails[]> {
return this.registryService.getFullRegistryUniversity();
}
disconnect() {}
}
编辑:
html:
<div>
<mat-table [dataSource]="dataSource">
<ng-container matColumnDef="graduateRut">
<mat-header-cell *matHeaderCellDef> RUT </mat-header-cell>
<mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.graduateRut}} </mat-cell>
</ng-container>
<ng-container matColumnDef="major">
<mat-header-cell *matHeaderCellDef> E-Mail </mat-header-cell>
<mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.major}} </mat-cell>
</ng-container>
<ng-container matColumnDef="university">
<mat-header-cell *matHeaderCellDef> University </mat-header-cell>
<mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.university}} </mat-cell>
</ng-container>
<ng-container matColumnDef="gradYear">
<mat-header-cell *matHeaderCellDef> GradYear </mat-header-cell>
<mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.gradYear}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
答案 0 :(得分:2)
您假设您是正确的,您在初始化uid之前正在调用API,因此会出现错误。
我们可以尝试通过多种方法来解决此问题,我将提供一个解决方法。
首先,将服务中的uid更改为BehaviorSubject:
uid = new BehaviorSubject<any>(null);
现在在构造函数中:
this.user.subscribe(
(user) => {
if (user) {
this.userDetails = user;
console.log(this.userDetails.email);
this.uid.next(this.userDetails.uid);
}
else {
this.userDetails = null;
}
}
);
应更改为支持BehviorSubject的http发布请求:
getFullRegistryUniversity(): Observable<DegreeDetails[]> {
let uidString = {
"uid" : this.uid.value // <-- here
}
return this.http.post<DegreeDetails[]>(this.serviceUrl, uidString)
}
并添加此get方法:
getUidObservable() {
return this.uid.asObservable()
}
在组件中,不要一开始就初始化数据源,而是等待UID变为可行的值。
dataSource: UserDataSource;
ngOnInit() {
this.registryService.getUidObservable().subscribe(_uid => {
if(_uid !== null) {
dataSource = new UserDataSource(this.registryService);
}
}
}
最后一件事,在您的html中,添加到wrap div中:
<div *ngIf="dataSource">
希望它能解决并解决您的问题。也许会有更快的方法,但是我认为这可以确保您的通话安全。