Search code examples
angularspartacus-storefront

Can I use Angular inject function when extending Spartacus components/services?


When I'm extending Spartacus component or service, and I want to add a new dependency via DI (Dependency Injection), I have to extend the original constructor and pass all it's dependencies. Is there a simpler way to do it? e.g. with the new Angular's inject() function?

For example, the default Spartacus class is:

export class CmsPageGuard {
  constructor(
    protected routingService: RoutingService,
    protected cmsService: CmsService,
    protected protectedRoutesGuard: ProtectedRoutesGuard,
    protected service: CmsPageGuardService,
    protected routingConfig: RoutingConfigService
  ) {}

  /*...*/

And when I want to add a new dependency, e.g. WindowRef, I have to repeat all the original dependencies and add the new one in the end:

export class CustomCmsPageGuard extends CmsPageGuard {
  constructor(
    protected routingService: RoutingService,
    protected cmsService: CmsService,
    protected protectedRoutesGuard: ProtectedRoutesGuard,
    protected service: CmsPageGuardService,
    protected routingConfig: RoutingConfigService,
    protected windowRef: WindowRef // MY NEW USED DEPENDENCY
  ) {
    super(
      routingService,
      cmsService,
      protectedRoutesGuard,
      service,
      routingConfig
    );
  }

  someCustomLogicExampleUsingNewDependency() {
    if(this.windowRef.isBrowser()) 
      /* ... */
    }
  }
}

Solution

  • Yes, there is a simpler way since Angular 14 the new inject function was introduced and now you can use it to inject your new dependencies without the need to touch the original constructor. Here's the example:

    import { inject } from '@angular/core';
    
    /* ... */
    
    export class CustomCmsPageGuard extends CmsPageGuard {
      protected windowRef = inject(WindowRef);
    
      someCustomLogicExampleUsingNewDependency() {
        if(this.windowRef.isBrowser()) {
          /* ... */
        }
      }
    }