spartacus icon indicating copy to clipboard operation
spartacus copied to clipboard

Outlets duplicated in Spartacus 6

Open JudithMMolina opened this issue 2 years ago • 9 comments

Describe the bug Outlets are duplicated post Spartacus upgrade 6.2

Tell us the version of Spartacus

  • Library version: 6.2.0

To Reproduce Steps to reproduce the behavior:

  1. Create a component to inject with OutletPosition
  2. Inject this component BEFORE or AFTER another component
  3. Go to the page where these components are
  4. The component is duplicated

Expected behavior This component shouldn't be duplicated

Screenshots image

Desktop (please complete the following information):

  • OS: Windows
  • Browser: Google Chrome

Additional context The project was initially on spartacus 4.3 and has been migrated to 6.2.

JudithMMolina avatar Aug 01 '23 07:08 JudithMMolina

Me pasa lo mismo siempre que uso el método provideOutlet(). Por ejemplo: provideOutlet({ id: CartOutlets.ORDER_SUMMARY, component: OrderSummaryComponent, }),

aravello-cassinelli avatar Aug 03 '23 18:08 aravello-cassinelli

Is there any investigation on this issue or a workaround?

muhammedmisir avatar Sep 08 '23 12:09 muhammedmisir

I had the same issue during the upgrade to the 5 version. Here's what I found:

Issue: Component duplication may occur if the outlet configuration module is imported multiple times (either indirectly or directly) within the SpartacusFeaturesModule.

   // Module A 
   @NgModule({
     imports: [...],
     providers: [
      provideOutlet({
        id: customOutlets.TEST,
        component: TestComponent,
      }),
     ]
   })
   export class ModuleA { }
   
   // Module B
   @NgModule({
     imports: [ModuleA],
   })
   export class ModuleB { }
   
   // Module C
   @NgModule({
     imports: [ModuleA],
   })
   export class ModuleC { }


   // Spartacus feature module
   @NgModule({
     imports: [
      ModuleB, // This line will create the first TestComponent
      ModuleC, // This will create the second TestComponent
     ],
   })
   export class SpartacusFeaturesModule { }

Solutions:

  1. Restructure Modules: Organize your modules to prevent importing the outlet configuration module multiple times inside the SpartacusFeaturesModule.

  2. Create a Dedicated Module: Designate a specific module to provide outlet configurations. Example:

// Module A 
@NgModule({
  imports: [...], // provideOutlet config was removed from this module
  declarations: [...],
  exports: [TestComponent],
})
export class ModuleA { }

// Module B
@NgModule({
  imports: [ModuleA],
})
export class ModuleB { }

// Module C
@NgModule({
  imports: [ModuleA],
})
export class ModuleC { }

// OutletConfigModule (Provide outlet configurations here)
@NgModule({
  imports: [ModuleA],
  providers: [
    provideOutlet({
      id: customOutlets.TEST,
      component: TestComponent,
    }),
  ]
})
export class OutletConfigModule { }

// Spartacus feature module
@NgModule({
  imports: [
    ModuleB, 
    ModuleC,
    OutletConfigModule // This line will create the TestComponent
  ],
})
export class SpartacusFeaturesModule { }

sebospc avatar Sep 21 '23 05:09 sebospc

@sebospc do any of these modules use OutletModule.forChild(), and also are they lazy loaded?

kpawelczak avatar Nov 28 '23 11:11 kpawelczak

@kpawelczak No, the modules in the example are eager modules but they could be lazy modules

sebospc avatar Feb 14 '24 04:02 sebospc

@sebospc Hi! Such, your solution doesn't work for us, I didn't find any OutletModule imports as well as OutletService providers in our project. We provide only one outlet and it's placed twice on a page.

Zwezh avatar Jun 10 '24 12:06 Zwezh

@sebospc Hi! Such, your solution doesn't work for us, I didn't find any OutletModule imports as well as OutletService providers in our project. We provide only one outlet and it's placed twice on a page.

Ensure that OutletModule.forChild() is not being called twice, which can lead to component duplication.

sebospc avatar Jun 10 '24 17:06 sebospc

@sebospc We got the project from previous suppliers and there is a lot of mess now, they have just hidden duplicated parts using 'display: none' instead of looking for a problem. Yesterday it was solved partially in a way by removing duplicated imported modules.

Zwezh avatar Jun 11 '24 08:06 Zwezh

@sebospc Whenever I want to configure a custom Component to replace the standard one for the Outlet id: CartOutlets.ORDER_SUMMARY I get the duplicates in e.g. Order History Page, Checkout and Order Confirmation Page.

I believe this is as you said because OutletModule.forChild() is called in CartBaseComponentsModule which imports the original outlet config from CartSharedModule. In this case the cause lies in the standard code, causing the duplication and making it impossible for me to change it without actually replacing all of the components referencing the mentioned CartOutlets.ORDER_SUMMARY. SAP should change this in my eyes.

felix-ka avatar Aug 05 '24 12:08 felix-ka