我正在使用spring作为后端创建网站,并使用angular和html作为前端。
我的MySQL数据库中有两个表(服务/报价)(offers表具有serviceName外键,该键同时是服务表的主键)。
我有一个角度组件,该组件调用两个数据库表并将它们放入两个不同的数组中。
我试图按角度创建一个新数组,该数组具有在offers数组中每个serviceName出现的次数,但是当我尝试记录(console.log)新列表时,有时它是空的,有时甚至没有出现
以下是角度分量:
import { Component, OnInit } from '@angular/core';
import { UserService } from '../user.service';
@Component({
selector: 'app-offrea',
templateUrl: './offrea.component.html',
styleUrls: ['./offrea.component.scss']
})
export class OffreaComponent implements OnInit {
loginuser: any = {};
offres: any[] = [];
services: any[] = [];
countList: any[] = [];
count: number;
constructor(private service: UserService) {
this.service.getAllOffer().subscribe(o => {
this.offres = o;
});
this.service.getServices().subscribe(ser => {
this.services = ser;
});
this.f(this.offres, this.services);
console.log(this.countList);
}
ngOnInit() {
}
f(a1, a2) {
for (let i = 0; i < a1.length; i++) {
this.count = 0;
for (let z = 0; z < a2.length; z++) {
if (a1[i].services.serviceName === a2[z].serviceName) {
this.count++;
this.countList.push(this.count);
}
}
this.count = 0;
}
}
}
答案 0 :(得分:0)
所以问题是您正在以同步方式调用两个异步函数(正在发出HTTP请求的subscribes
)。意思是,当您到达this.f(...)
和console.log
呼叫时,您的http呼叫 或可能尚未完成。
解决方案是将您的订阅合并为一个函数,并在订阅回调中调用this.f(...)
和console.log
。您可以使用RxJS combineLastest或forkJoin。我在答案中使用了forkJoin
,因为http可观察对象已完成。
这是一个包含工作代码的堆栈闪电(已模拟出user.service.ts)。 https://stackblitz.com/edit/angular-zvfsft
在 offera.component.ts
中// beginning of file...
/* I recommend moving your logic to ngOnInit */
ngOnInit() {
// You need to combine your two calls
// you can use combineLatest or forkJoin
forkJoin(
this.service.getAllOffer(),
this.service.getServices(),
).subscribe(([offres, services]) => {
this.offres = offres;
this.services = services;
this.f(this.offres, this.services);
console.log(this.countList);
});
}
// rest of file...
forkJoin
和combineLatest
之间的主要区别是:
forkJoin
要求在将值传递给订阅者之前完成所有可观察项。这被视为“冷”可观察物,因为它只会发射一次。 combineLatest
要求所有可观察对象至少发射一次,然后再将任何值传递给订阅者。它还有其他一些很棒的行为,但是最重要的是,这通常返回一个可观察到的热点。如果您想了解更多,请阅读此文档。 希望这对您有用。干杯!