简体   繁体   中英

Angular component rendered before API response completed

I'm developing an application with angular 8. I have a parent component (Bid) contains some child components (service1, service2), each child component loading some data dynamically according to data, this data came from an API. I'm calling this API in the parent component (Bid).

The problem is at some time the controls are rendered before the API is completed so the page appear empty.

I tried to call the API in ngOnInit() and in constructor() but the result is the same.

component hierarchy is as follows:

RequestDetails ==> Bid ==> (Service1, Service2)

RequestDetails:

constructor(private activatedRoute: ActivatedRoute, public common: CommonService, public bidService: BidsService) {
this.activatedRoute.paramMap.subscribe((param) => {
  
  let bidID = param.get('bidId');
  if (bidID != null) {
    this.bidService.setMode('edit');
    this.getRequestDetails(param.get('id')).then(res => this.bidService.fillEditFields(bidID)) // Get fields values
  }
  else{
    this.getRequestDetails(param.get('id'));
    this.bidService.setMode('create');
  }
})}

Bid:

constructor(public common: CommonService, public bidsService: BidsService, private activatedRoute: ActivatedRoute, public router: Router) {
this.loading = true;
this.bidsService.bidValue.subscribe(p => this.bid = p);
this.bidsService.bidRequestDetails.subscribe(p => this.bidRequestDetails = p);}

Bid Html:

<app-net-rate-item [isFCL]="isFCL" *ngFor="let container of filterNetRate(getCurrentEditNetRate(),1)"
    [cargoDetailsId]="0" [netRateContainerType]="container.netRateContainerType"
    [netRateContainerTypeId]="container.netRateContainerTypeId" [netRateContainerAmount]="container.netRateAmount"
    (valueChange)="getNetRateValue($event, container.netRateId, 1)" [netRateType]="1" [sourceType]="sourceType"
    [disabled]="sourceType === 1 ? bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled"
    [required]="(sourceType === 1 ? !bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : !bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled)"
    [validate]="validateEvent" [value]="container">
  </app-net-rate-item>

You can use *ngIf to hide/show components or any HTML elements, in your example you have to provide a boolean property to get the current state as follows:

Bid.ts

    show = false;
    constructor(public common: CommonService, public bidsService: BidsService, private activatedRoute: ActivatedRoute, public router: Router) {
    this.loading = true;
    this.bidsService.bidValue.subscribe(p => this.bid = p);
    this.bidsService.bidRequestDetails.subscribe(p => {
this.bidRequestDetails = p;
this.show = true;  // to update the state
});}

Bid Html:

<div *ngIf='show'>
    <app-net-rate-item [isFCL]="isFCL" *ngFor="let container of filterNetRate(getCurrentEditNetRate(),1)"
        [cargoDetailsId]="0" [netRateContainerType]="container.netRateContainerType"
        [netRateContainerTypeId]="container.netRateContainerTypeId" [netRateContainerAmount]="container.netRateAmount"
        (valueChange)="getNetRateValue($event, container.netRateId, 1)" [netRateType]="1" [sourceType]="sourceType"
        [disabled]="sourceType === 1 ? bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled"
        [required]="(sourceType === 1 ? !bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : !bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled)"
        [validate]="validateEvent" [value]="container">
      </app-net-rate-item>
</div>

Just to mention you could add <ng-container> instead of the outside div element since it is a grouping element that doesn't interfere with styles or layout and Angular doesn't put it in the DOM.

or you could use hidden in Bid.Html also:

    <app-net-rate-item [hidden]='!show' [isFCL]="isFCL" *ngFor="let container of filterNetRate(getCurrentEditNetRate(),1)"
        [cargoDetailsId]="0" [netRateContainerType]="container.netRateContainerType"
        [netRateContainerTypeId]="container.netRateContainerTypeId" [netRateContainerAmount]="container.netRateAmount"
        (valueChange)="getNetRateValue($event, container.netRateId, 1)" [netRateType]="1" [sourceType]="sourceType"
        [disabled]="sourceType === 1 ? bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled"
        [required]="(sourceType === 1 ? !bid.mainService.originOtherExpensePerShipmentMainService.isDisabled : !bid.mainService.destinationOtherExpensePerShipmentMainService.isDisabled)"
        [validate]="validateEvent" [value]="container">
      </app-net-rate-item>

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM