I am calling a service method(findDebtorName) from a component oninit method which calls findDebtor method. this.debtors is subscribed and data reaches late. this.debtors.find in findDebtor method is called before data is in this.debtors due to which I am facing find of undefined error
Component file
ngOnInit(): void {
this.documentService.currentDocument = null;
this.filteredDocs = this.documents.map((doc) => {
doc.company = this.debtorService.findDebtorName(doc.debtors[0]);
return doc;
});
this.creditOverviewSortingService.onSortChange(this.sortDocuments.bind(this));
this.filteredDocuments();
}
service file
@Injectable()
export class DebtorService {
customerGroup: Debtor;
debtors: Debtor[];
constructor(private sharedDataService: SharedDataService, private http: HttpClient) {
this.sharedDataService.customerGroup.subscribe((customerGroup) => {
this.customerGroup = new Debtor(customerGroup);
});
this.sharedDataService.debtors.subscribe((debtors) => {
this.debtors = debtors;
});
}
findDebtorName(debtorId: string): string {
const correctDebtor = this.findDebtor(debtorId);
return correctDebtor ? correctDebtor.name : 'DEBTOR NOT FOUND';
}
findDebtor(debtorId: string): Debtor {
return this.debtors.find((debtor) => debtor.id === debtorId);
}
}
Kindly let me know what I am doing wrong.
You could make sure that the async data this.customerGroup
and this.debtors
are defined before trying to access them. And since there are 2 async data involved the complete flow need to be async as well to make sure the data is initialized before processing them.
Service
@Injectable()
export class DebtorService {
customerGroup: Debtor;
debtors: Debtor[];
constructor(private sharedDataService: SharedDataService, private http: HttpClient) { }
initializeData(): Observable<any> {
return combineLatest([this.sharedDataService.customerGroup, this.sharedDataService.debtors]).pipe(
take(1),
tap(response => {
this.customerGroup = response[0];
this.debtors = response[1];
}),
catchError(error => {
// handle error
return of(error);
})
);
}
findDebtorName(debtorId: string): string {
return this.findDebtor(debtorId).pipe(
map(correctDebtor => {
return correctDebtor ? correctDebtor.name : 'DEBTOR NOT FOUND';
})
);
}
findDebtor(debtorId: string): Debtor {
return this.initializeData().pipe(
map(response => {
return this.debtors.find((debtor) => debtor.id === debtorId);
})
);
}
}
Component
ngOnInit(): void {
this.documentService.currentDocument = null;
forkJoin(this.documents.map((doc) => this.debtorService.findDebtorName(doc.debtors[0]))).subscribe(
response => {
this.documents.forEach(doc, index => {
doc.company = response[index];
});
}
);
this.creditOverviewSortingService.onSortChange(this.sortDocuments.bind(this));
this.filteredDocuments();
}
Note that the this.documents
is also modified asynchronously in the ngOnInit
of the component.
You should make sure the data loaded before call findDebtorName().
@Injectable()
export class DebtorService {
customerGroup: Debtor;
debtors: Debtor[];
constructor(
private sharedDataService: SharedDataService,
private http: HttpClient,
) {}
async loadData() {
// get data parallelly
const data = await Promise.all([
this.sharedDataService.customerGroup.toPromise,
this.sharedDataService.debtors.toPromise,
])
const customerGroup = new Debtor(data[0]) ;
const debtors = data[1];
}
findDebtorName(debtorId: string): string {
const correctDebtor = this.findDebtor(debtorId);
return correctDebtor ? correctDebtor.name : 'DEBTOR NOT FOUND';
}
findDebtor(debtorId: string): Debtor {
return this.debtors.find(debtor => debtor.id === debtorId);
}
}
async ngOnInit(): Promise<void> {
// load data before call any function which depends on this data
await this.debtorService.loadData();
this.documentService.currentDocument = null;
this.filteredDocs = this.documents.map((doc) => {
doc.company = this.debtorService.findDebtorName(doc.debtors[0]);
return doc;
});
this.creditOverviewSortingService.onSortChange(this.sortDocuments.bind(this));
this.filteredDocuments();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.