Route guard changes when extending routes

Sterling Store Engagement uses the Angular route guards to control navigation to certain routes that are based on conditions. Therefore, when you extend routes, certain changes are made to the route guard.

For example, the ValidatePackOrderGuard angular route guard that is present in the store-single-spa/packages/features/pack-order/src/app/features/pack-order/pack-order-page/validate-pack-order.guard.ts file is used to validate if a shipment is in a valid status before you move to the Pack products page. If the shipment is not in the valid status, the Pack products page is not displayed.

The Angular route guards need to be changed when you extend any route that is protected by the routing guard. For example, if you extend the PackOrderPageComponent in the pack flow, modify the ValidatePackOrderGuard angular route guard.

To modify the ValidatePackOrderGuard angular route guard, complete the following steps:
  1. In the data service file used by the route, add the routingInProgress$ subject. In this case, PackOrderPageDataService is the data service.
    import { Subject } from 'rxjs';
    public routingInProgress$: Subject<boolean> = new Subject<boolean>();
  2. In the route guard, add the routingInProgress variable as follows:
    public routingInProgress = false;
  3. Include the code in the canActivate method within the if(!this.routingInProgress) block.
  4. Set the routingInProgress) to true.
  5. In the promise handler, reset the routingInProgress to false, and emit routingInProgress$.next(false).
  6. Add this._location.back(); statement in the else block as illustrated in the following code snippet. You can find the changes within //Extension changes - start // and //Extension changes - end // comment.
    /*******************************************************************************
    * IBM Confidential
    * IBM Sterling Order Management (5737-D18)
    * IBM Sterling Order Management Software (5725-D10)
    * (C) Copyright IBM Corp. 2022
    ******************************************************************************/
    
    import { Location } from '@angular/common';
    import { Injectable } from '@angular/core';
    import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, UrlTree } from '@angular/router';
    import { routePath, UIUtil } from '@store/core';
    import { PackOrderPageDataService } from './pack-order-page-data.service';
    
    @Injectable()
    export class ValidatePackOrderGuard implements CanActivate {
    
      private shipmentId = '';
      // Extension changes - start //
      public routingInProgress = false;
       // Extension changes - end //
      constructor(
        private packOrderDataService: PackOrderPageDataService,
        private router: Router,
        private _location: Location
      ) { }
    
      canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Promise<boolean | UrlTree> | boolean | UrlTree {
    
        this.shipmentId = next.params['ShipmentNo'];
        //Extension changes - start //
        if(!this.routingInProgress){
        this.routingInProgress = true; 
        this.packOrderDataService.routingInProgress$.next(true);
        //Extension changes - end //
        return this.packOrderDataService.validatePackReqBeforePack(this.shipmentId)
          .then(
            validationStatus => {
             let validationState = validationStatus['Shipment'] && !validationStatus['Shipment'].Error ? 'continueToPack' : validationStatus;
             //Extension changes - start //
              this.routingInProgress = false;
              this.packOrderDataService.routingInProgress$.next(false);
             //Extension changes - end //
              if (validationState === 'continueToPack') {
                return true;
              } else if (validationStatus['Shipment'] && validationStatus['Shipment'].Error && validationStatus['Shipment'].Error.ErrorDescription) {
                const navigationURL = routePath(`shipment/summary/${this.shipmentId}`, 'shell');
                const queryParams = { errorMsg: validationStatus['Shipment']?.Error?.ErrorDescription };
                if (this.router.url === '/') {
                  history.replaceState('', '', '/' + navigationURL + UIUtil.jsonToQueryString(queryParams));
                }
                return this.router.createUrlTree([navigationURL], { queryParams: queryParams });
              } else {
                if (this.router.url === '/') {
                  this._location.back();
                  return true;
                } else {
                  //Extension changes - start //
                  this._location.back();
                  //Extension changes - end //
                  return false;
                }
              }
            }
          );
        }
      }
    }
  7. Subscribe to routingInProgress$ in the route component ngOnInit method. For example, within PackOrderPageComponent
    this.dataService.routingInProgress$.subscribe(routingInProgress => {
     if(!routingInProgress){
      this.packAllPermission = ResourcePermissionUtil.hasPermission(this.PACKALL_RESOURCE_PERMISSION);
      this.showItemImage = RulesUtil.isRuleEnabled('WSC_SHOW_ITEM_IMAGES');
      this.shipmentKey = this.activeRoute.snapshot.params['ShipmentNo'];
      this.getInitializationDataForShipment(true);
     }
     });