David Levy
David Levy

Reputation: 1

SAP Spartacus 2211: Override OccCartAdapter to add extra params to /email query

In SAP Spartacus 2211, I need to add 2 more params to the request that adds a guest customer to the backend. The endpoint is called addEmail:

addEmail: 'users/${userId}/carts/${cartId}/email'

Which is already sending the email address as an http param on the body request.

What I did was:

  1. Override CheckoutLoginComponent with custom one to add my extra fields in the UI
  2. Created a DataService to store the extra parameters
  3. Override the function onSubmit on my CustomCheckoutLoginComponent, to set the extra fields values in the new DataService.
  4. Created a CustomOccCartAdapter that extends OccCartAdapter, and overrides the function "addEmail", getting the extra fields from the injected DataService and adding them to the http request.

The problem is my CustomOccCartAdapter is not getting called, I tried several ways and can't find the proper steps to override the OOTB OccCartAdapter.

This is my CustomCheckoutLoginComponent:

import { Component } from '@angular/core';
import {CheckoutLoginComponent} from "@spartacus/checkout/base/components";
import {UntypedFormBuilder, Validators} from "@angular/forms";
import {AuthRedirectService} from "@spartacus/core";
import {ActiveCartFacade} from "@spartacus/cart/base/root";
import {SfLoginStateService} from "../cart/sf-login-state-service";

@Component({
  selector: 'app-sf-checkout-login',
  templateUrl: './sf-checkout-login.component.html',
  styleUrl: './sf-checkout-login.component.scss'
})
export class CustomCheckoutLoginComponent extends CheckoutLoginComponent {

  constructor(
    protected override formBuilder: UntypedFormBuilder,
    protected override authRedirectService: AuthRedirectService,
    protected override activeCartFacade: ActiveCartFacade,
    private customLoginStateService: CustomLoginStateService
  ) {
    super(formBuilder, authRedirectService, activeCartFacade);
    this.extendForm();
  }

  private extendForm() {
    this.checkoutLoginForm.addControl('firstName', this.formBuilder.control('', Validators.required));
    this.checkoutLoginForm.addControl('lastName', this.formBuilder.control('', Validators.required));
    this.checkoutLoginForm.addControl('phone', this.formBuilder.control('', Validators.required));
  }

  override onSubmit() {
    if (this.checkoutLoginForm.valid) {

      const firstName = this.checkoutLoginForm.get('firstName')?.value;
      const lastName = this.checkoutLoginForm.get('lastName')?.value;
      const name = firstName + " " + lastName;
      const phone = this.checkoutLoginForm.get('phone')?.value;
      this.customLoginStateService.setData(name, phone);

      const email = this.checkoutLoginForm.get('email')?.value;
      this.activeCartFacade.addEmail(email);

      if (!this.sub) {
        this.sub = this.activeCartFacade.isGuestCart().subscribe((isGuest) => {
          if (isGuest) {
            this.authRedirectService.redirect();
          }
        });
      }
    } else {
      this.checkoutLoginForm.markAllAsTouched();
    }
  }

}

This is my custom adapter:

import {Injectable} from "@angular/core";
import {OccCartAdapter} from "@spartacus/cart/base/occ";
import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
import {ConverterService, InterceptorUtil, OccEndpointsService, USE_CLIENT_TOKEN} from "@spartacus/core";
import {SfLoginStateService} from "./sf-login-state-service";
import {Observable} from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class CustomOccCartAdapter extends OccCartAdapter {
  constructor(
    protected override http: HttpClient,
    protected override occEndpointsService: OccEndpointsService,
    protected override converterService: ConverterService,
    private customLoginStateService: CustomLoginStateService
  ) {
    super(http, occEndpointsService, converterService);
  }

  override addEmail(userId: string, cartId: string, email: string): Observable<{}> {
    let headers = new HttpHeaders({
      'Content-Type': 'application/x-www-form-urlencoded',
    });
    headers = InterceptorUtil.createHeader(USE_CLIENT_TOKEN, true, headers);

    const customerData = this.customLoginStateService.getData();

    const httpParams: HttpParams = new HttpParams();
    httpParams.set('email', email);
    httpParams.set('name', customerData.name);
    httpParams.set('phone', customerData.phone);

    const url = this.occEndpointsService.buildUrl('addEmail', {
      urlParams: {
        userId,
        cartId,
      },
    });

    return this.http.put(url, httpParams, { headers });
  }
}

I tried doing this in my app.module.ts :

providers: [{
  provide: CartAdapter,
  useClass: CustomOccCartAdapter
}
...
]

But didn't work, the OOTB adapter is still being called.

How to I get the OOTB OccCartAdapter effectively overriten by my CustomOccCartAdapter ?

Upvotes: 0

Views: 159

Answers (1)

MickeyMan
MickeyMan

Reputation: 1

Please provide your custom Adapter not in the app.module but in a lazy-loaded custom "wrapper" module as CartAdapter is part of CartBaseOccModule which is lazy-loaded OOTB.

For docs please take a look at this Customizing Lazy Loaded Feature Modules

Upvotes: 0

Related Questions