NgxAdmin freezes when load large Amount of nested data in Angular 11

27 views Asked by At

using get by id API we fetch data for particular id in Angular 11

this is our form group

export class PromotionsService extends HttpService<Promotion> {
  form: FormGroup;
  
  constructor(public http: HttpClient, private fb: FormBuilder) {
    super('promotions', http);
    this.resetForm();
  }

  resetForm() {
    this.form = this.fb.group({
      siteCodeId: ['', Validators.required],
      description: ['', Validators.required],
      promotionDealsTitle: ['', Validators.required],
      flightRegionPromotions: this.fb.array([], Validators.required),
    });
  }
  createFlightRegionPromotion(flightRegionPromotionOrder: number) {
    return this.fb.group({
      id: [0],
      flightRegionId: ['', Validators.required],
      status: [true],
      order: [
        flightRegionPromotionOrder,
        [Validators.required, Validators.min(1)],
      ],
      promotionDeals: this.fb.array(
        [this.createPromotionDeal(1)],
        Validators.required,
      ),
    });
  }

  addFlightRegionPromotion(flightRegionPromotionOrder: number) {
    const flightRegionPromotions = this.form.get(
      'flightRegionPromotions',
    ) as FormArray;

    flightRegionPromotions.push(
      this.createFlightRegionPromotion(flightRegionPromotionOrder),
    );
  }
  removeFlightRegionPromotion(removeIndex: number) {
    const flightRegionPromotions = this.form.get(
      'flightRegionPromotions',
    ) as FormArray;
  flightRegionPromotions.removeAt(removeIndex);
  }

  createPromotionDeal(order: number) {
    return this.fb.group({
      id: [0],
      flightRegionPromotionId: [''],
      status: [true],
      fromDestinationsListId: ['', Validators.required],
      toDestinationsListId: ['', Validators.required],
      airlineId: ['', Validators.required],
      price: ['', Validators.required],
      currency: ['', Validators.required],
      order: [order, [Validators.required, Validators.min(1)]],
      image: this.fb.group({
        path: ['', Validators.required],
        type: [''],
        alt: [''],
      }),
    });
  }

  addPromotionDeal(
    flightRegionPromotionIndex: number,
    promotionDealOrder: number,
  ) {
    const flightRegionPromotions = this.form.get(
      'flightRegionPromotions',
    ) as FormArray;
    const promotionDeals = flightRegionPromotions.controls[
      flightRegionPromotionIndex
    ].get('promotionDeals') as FormArray;

    promotionDeals.push(this.createPromotionDeal(promotionDealOrder));
  }

  removePromotionDeal(
    flightRegionPromotionIndex: number,
    promotionDealIndex: number,
  ) {
    const flightRegionPromotions = (
      this.form.get('flightRegionPromotions') as FormArray
    ).controls[flightRegionPromotionIndex];

    const promotionDeals = flightRegionPromotions.get(
      'promotionDeals',
    ) as FormArray;
  
// **TYPESCRIPT FILE**

@Component({
  selector: 'ngx-promotions-edit',
  templateUrl: './promotions-edit.component.html',
  styleUrls: ['./promotions-edit.component.scss'],
  // changeDetection: ChangeDetectionStrategy.OnPush
})
export class PromotionsEditComponent
  extends PromotionsCreateComponent
  implements OnInit, OnDestroy, AfterViewChecked, AfterViewInit {
  private destroy$ = new Subject<void>();
  id: number;
  public Editor = ClassicEditor;
flightRegionData:FlightRegionPromotion[]=[];

  constructor(
    public siteCodesService: SiteCodesService,
    public toastrService: NbToastrService,
    public router: Router,
    public cdRef: ChangeDetectorRef,
    public mediaUploadService: MediaUploadService,
    public generalService: GeneralService,
    public authService: AuthService,
    public promotionsService: PromotionsService,
    public flightRegionService: FlightRegionService,
    public hotelbedsService: HotelbedsService,
    public route: ActivatedRoute,
    private fb: FormBuilder,
  ) {
    super(
      siteCodesService,
      toastrService,
      router,
      cdRef,
      mediaUploadService,
      generalService,
      authService,
      promotionsService,
      flightRegionService,
      hotelbedsService,
    );

    route.params.subscribe((params) => {
      this.id = params.id;
    });
  }

  ngOnInit(): void {
    this.loadData();
      }
  }

  ngAfterViewInit() {
    // setInterval(() => {
    //   const expirationTime = localStorage.getItem(
    //     `promotions-expirationTime${this.id}`,
    //   );

    //   if (expirationTime != null) {
    //     const currentTime = new Date().getTime();
    //     const expr = new Date(parseInt(expirationTime, 10)).getTime();
    //     const different = expr - currentTime;
    //     const remainMinutes = Math.floor(different / (60 * 1000));
    //     const remainSeconds = Math.floor((different % (60 * 1000)) / 1000);

    //     this.minutes.nativeElement.innerText = remainMinutes.toLocaleString(
    //       'en-GB',
    //       { minimumIntegerDigits: 2, useGrouping: false },
    //     );
    //     this.seconds.nativeElement.innerText = remainSeconds.toLocaleString(
    //       'en-GB',
    //       { minimumIntegerDigits: 2, useGrouping: false },
    //     );

    //     if (remainMinutes <= 0 && remainSeconds <= 0) {
    //       localStorage.removeItem(`promotions-expirationTime${this.id}`);
    //       if (this instanceof PromotionsEditComponent) {
    //         this.toastrService.show('Time Out', `Time Out`, {
    //           status: 'danger',
    //         });
  
    //       }
    //     }
    //   }
    // }, 1000);
  }

  loadData(){
    forkJoin([  this.generalService.getAllDestinationList(),
      this.siteCodesService.all(),
      this.flightRegionService.getAllFlightRegions(),
      this.generalService.getAllAirlines(),
      this.hotelbedsService.getAllCurrencyList(),
      this.promotionsService.find(this.id)
    ]).subscribe(([destinationList,sites,flightRegions,airlines,currencies,promotion])=>{
     this.originalDestinationList= destinationList;
     this.sites=sites;
     this.flightRegions=flightRegions;
     this.originalAirlines=airlines;
     this.currencies=currencies;
     this.getAllDestinationList();
     this.getAllSites();
     this.getAllAirlines();
     this.getHBCurrencyList();
     this.fetchPromotion(promotion);

     this.loading = false;
     
    },
    (error) => {
      this.loading = false
    })
  }

  fetchPromotion(promotion:Promotion) {
  
    if (promotion) {
      if (promotion.video == null)
        this.promotionForm.get('video.path').setValue('');

      (this.promotionForm.get('heroImages') as FormArray).clear();

      if (promotion.heroImages != null) {
        promotion.heroImages.map((image) => {
          (this.promotionForm.get('heroImages') as FormArray).push(
            this.fb.group({
              path: new FormControl(image.path),
              alt: new FormControl(image.alt),
              type: new FormControl(image.type),
            }),
          );
        });
      }

      const flightRegionPromotions = this.promotionForm.get(
        'flightRegionPromotions',
      ) as FormArray;
this.flightRegionData=promotion.flightRegionPromotions;
      flightRegionPromotions.clear();
  this.promotionForm.patchValue(promotion);
      this.loading = false;
    
    }
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  onNextDataAddHandler(){
    this.promotionFormStepper.next();
    const stepIndex = this.promotionFormStepper.selectedIndex;
if (this.flightRegionData != null) {
  const flightRegionPromotions = this.promotionForm.get(
    'flightRegionPromotions',
  ) as FormArray;
        this.flightRegionData.forEach((region, regionIndex) => {
          let promotionDeals: FormGroup[] = [];
          if (region.promotionDeals != null) {
            promotionDeals = region.promotionDeals.map(
              (deal, dealIndex) => {
                return this.fb.group({
                  id: new FormControl(deal?.id),
                  flightRegionPromotionId: new FormControl(
                    deal?.flightRegionPromotionId,
                  ),
                  status: new FormControl(deal?.status),
                  fromDestinationsListId: new FormControl(
                    deal?.fromDestinationsListId,
                    Validators.required,
                  ),
                  toDestinationsListId: new FormControl(
                    deal?.toDestinationsListId,
                    Validators.required,
                  ),
                  airlineId: new FormControl(
                    deal?.airlineId,
                    Validators.required,
                  ),
                  price: new FormControl(deal?.price, Validators.required),
                  currency: new FormControl(
                    deal?.currency,
                    Validators.required,
                  ),
                  order: new FormControl(deal?.order, [
                    Validators.required,
                    Validators.min(1),
                  ]),
                  image: new FormGroup({
                    path: new FormControl(
                      deal?.image?.path,
                      Validators.required,
                    ),
                    type: new FormControl(deal?.image?.type),
                    alt: new FormControl(deal?.image?.alt),
                  }),
                });
              },
            );
          }
          flightRegionPromotions.push(
            this.fb.group({
              id: [region.id],
              flightRegionId: [region.flightRegionId],
              status: [region.status],
              order: [
                region.order,
                [Validators.required, Validators.min(1)],
              ],
              promotionDeals: this.fb.array(promotionDeals),
            }),
          );
        });
      }
  }
}
<nb-card [ngClass]="{ 'edit-promotion-card': loading === true }">
  <nb-card-header class="d-flex justify-content-between align-items-center">
    <span> Edit Promotion : {{ id }} </span>
  </nb-card-header>
  <nb-card-body *ngIf="loading" class="edit-nb-card-body">
    <ngx-loader> </ngx-loader
  ></nb-card-body>
  <nb-card-body>
    <form [formGroup]="promotionForm">
      <nb-stepper #promotionFormStepper orientation="horizontal">
        <!--details-->
        <nb-step [label]="details" completed>
          <ng-template #details>Details</ng-template>
          <nb-card>
            <nb-card-body>
              <div class="row">
                
                <div class="col-md-6">
                  <div class="form-group">
                    <label for="descriptionTitle" class="label"
                      >Description Title</label
                    >
                    <input
                      type="text"
                      nbInput
                      fullWidth
                      id="descriptionTitle"
                      placeholder=""
                      formControlName="descriptionTitle"
                      class="is-invalid"
                    />
                  </div>
                </div>
             
                </div>
              </div>
            </nb-card-body>
          </nb-card>
          <!-- nbStepperNext -->
          <div class="row no-gutters justify-content-end w-100">
            <button nbButton  (click)="onNextDataAddHandler()" class="next-btn">next</button>
          </div>
        </nb-step>
        <nb-step [label]="promotiondeals" completed>
          <ng-template #promotiondeals>Promotion Deals</ng-template>
          <nb-card  formArrayName="flightRegionPromotions"
            *ngFor="
              let region of flightRegionPromotionsControls;
              let regionIndex = index
            "
          >
            <!-- formGroupName regionIndex" START-->
            <div [formGroupName]="regionIndex">
              <nb-card-header
                class="d-flex justify-content-between align-items-center section-nb-header"
              >
                <span> Region {{ regionIndex + 1 }}</span>
              </nb-card-header>
              <nb-card-body>
                <div class="row pl-3 pr-3 pb-3">
                  <div class="col-md-3">
                    <label [for]="'flightRegionId' + regionIndex" class="label"
                      >Flight Region</label
                    >
                    <nb-select
                      fullWidth
                      placeholder="Flight Region"
                      formControlName="flightRegionId"
                      [id]="'flightRegionId' + regionIndex"
                    >
                      <nb-option
                        *ngFor="let option of flightRegions"
                        (selectionChange)="onFlightRegionChangeHandler()"
                        (click)="
                          onFlightRegionAvailableChangeClickHandler(
                            option.id,
                            regionIndex
                          )
                        "
                        [value]="option.id"
                        [id]="'flightRegionId' + regionIndex"
                      >
                        {{ option.name }}
                      </nb-option>
                    </nb-select>
                  </div>
                </div>
                <!-- promotionDeals START-->
                <div class="col-md-12">
                  <nb-card  formArrayName="promotionDeals"
                    *ngFor="
                      let deal of promotionDeals(regionIndex).controls;
                      let promotionDealIndex = index
                    "
                  >
                    <div [formGroupName]="promotionDealIndex">
                      <nb-card-header
                        class="d-flex justify-content-between align-items-center"
                      >
                        <span
                          >Region {{ regionIndex + 1 }} | Deal
                          {{ promotionDealIndex + 1 }}</span
                        >
                      </nb-card-header>
                      <nb-card-body>
                        <div class="row p-2">
                          <div class="col-md-4">
                            <div class="form-group">
                              <label
                                class="label"
                                [for]="
                                  'flight-region' +
                                  regionIndex +
                                  'promotion-deal-fromDestinationsListId' +
                                  promotionDealIndex
                                "
                                >From</label
                              >

                              <nb-select
                              fullWidth
                              placeholder="From"
                              formControlName="fromDestinationsListId"
                              [id]="
                              'flight-region' +
                              regionIndex +
                              'promotion-deal-fromDestinationsListId' +
                              promotionDealIndex
                            "
                            >
                                 <nb-option
                                *ngFor="let option of originalDestinationList"
                                
                                (click)="
                                promotionDealDestinationListFromClickHandler(
                                  $event,
                                  regionIndex,
                                  promotionDealIndex
                                )
                              "
                                [value]="option.id"
                                [id]="
                                'flight-region' +
                                regionIndex +
                                'promotion-deal-fromDestinationsListId' +
                                promotionDealIndex
                              "
                              >
                                
                                <div class="d-flex flex-column">
                                  <div>
                                    {{ option.airportName }} -({{
                                      option.airportCode
                                    }})
                                  </div>
                                  <div>
                                    {{ option.cityName }}
                                    -{{ option.countryName }}
                                  </div>
                                </div>
                              </nb-option>
                            </nb-select>
                        
                            </div>
                          </div>
                          <div class="col-md-4">
                            <div class="form-group">
                              <label
                                class="label"
                                [for]="
                                  'flight-region' +
                                  regionIndex +
                                  'promotion-deal-toDestinationsListId' +
                                  promotionDealIndex
                                "
                                >To</label
                              >
                              <nb-select
                              fullWidth
                              placeholder="From"
                              formControlName="toDestinationsListId"
                              [id]="
                              'flight-region' +
                              regionIndex +
                              'promotion-deal-toDestinationsListId' +
                              promotionDealIndex
                            "
                            >
                              <nb-option
                                *ngFor="let option of originalDestinationList"
                                
                                (click)="
                                promotionDealDestinationListToClickHandler(
                                  $event,
                                  regionIndex,
                                  promotionDealIndex
                                )
                              "
                                [value]="option.id"
                                [id]="
                                'flight-region' +
                                regionIndex +
                                'promotion-deal-toDestinationsListId' +
                                promotionDealIndex
                              "
                              >
                                
                                <div class="d-flex flex-column">
                                  <div>
                                    {{ option.airportName }} -({{
                                      option.airportCode
                                    }})
                                  </div>
                                  <div>
                                    {{ option.cityName }}
                                    -{{ option.countryName }}
                                  </div>
                                </div>
                              </nb-option>
                              </nb-select>
                            </div>
                          </div>
                          </div>
                      </nb-card-body>
                      <nb-card-footer>
                        <div
                          class="row no-gutters my-3 justify-content-end w-100"
                        >
                          <div
                            class="pr-2"
                          >
                            <button
                              nbButton
                              class="new-btn"
                              status="primary"
                              (click)="AddPromotionDealHandler(regionIndex)"
                              size="small"
                            >
                              Add New Deal
                            </button>
                          </div>
                          <div *ngIf="promotionDeals(regionIndex).length > 1">
                          </div>
                        </div>
                      </nb-card-footer>
                    </div>
                  </nb-card>
                  <!-- formArrayName promotionDeals End -->
                </div>
              </nb-card-body>
            </div>
          </nb-card>

          <div class="row no-gutters justify-content-end w-100">
            <button nbButton nbStepperPrevious class="mr-2 prev-btn">
              prev
            </button>
          </div>
        </nb-step>
      </nb-stepper>
    </form>
  </nb-card-body>
</nb-card>

when we fetch data flight Region has 6 array and each region has 8 promotion deals when we bind this using fetchPromotion(promotion) Application is stacked and cannot do any thing

After i change to add data during when click NEXT button it also take some time and when add new promotion deal it takes time to add new Deal view to user

when i check with js profiler 4 drop downs at promotion deals array is caused

Are there any ways to sort out this?

0

There are 0 answers