Search code examples
spartacus-storefront

How to share CMSComponentData between independent components in Spartacus


Let's imagine that we have CMS Component:

ConfigModule.withConfig(<CmsConfig>{
  cmsComponents: {
    CmsSupportComponent: {
      component: SupportComponent,
    },
  },
}),

But from inside we have to open another Angular component which also needs the same CMSComponentData. Simple Angular component relates to the same Angular module.

I know that we can do it via Angular Service, common for Angular manner (this requires some handy work). But maybe Spartacus has some approaches similar to:

ConfigModule.withConfig({
  cmsComponents: {
    CmsSupportComponent: {
        component: SupportComponent,
        providers: [
        {
          provide: SupportComponentService,
          useClass: SupportComponentService,
          deps: [CmsComponentData]
        }
      ];
    }
  }
});

and we can share injected CmsComponentData via common Service for independent components.

Update 21.01.2021:

When we say - 'open' Angular component from inside CMS Component, it's meaning something like that:

this.modalService.open(SupportFormComponent);

As you can see SupportFormComponent is not child component and don't have any relationships with CmsSupportComponent.


Solution

  • Angular uses hierarchical dependency tree, so any instance that you can inject in a parent component, you can also inject inside child component, unless it's shadowed be new provider (but even then @SkipSelf may help).

    So, as CmsComponentData is provided automatically by Spartacus, when instantiating specific cms component, it should be possible to inject it to any child component (inside this component) by just injecting CmsComponentData (you'll get the same instance).

    In case of some complex configuration, when you are providing different CmsComponentData in child components, you can always wrap it into service (or provide as different token) in the first (top) component that gets it, but I think in your case it should not be needed.