I am trying to implement a custom normalizer to the configurable product feature module. I have to include a custom field in the Attributes datatype. Currently only the OccConfigurationVariantNormalizer is available, which is quite high level form a data's point of view.
My problem occurs with the execution order of the normalizers. The default normalizer ist this: https://github.com/SAP/spartacus/blob/develop/feature-libs/product-configurator/rulebased/occ/variant/converters/occ-configurator-variant-normalizer.ts which is being called after my custom normalizer. Hence, the convertGroup() function is overriding my custom attribute field.
Here is my implementation:
@Injectable({
providedIn: 'root'
})
export class CustomConfiguratorNormalizerService extends OccConfiguratorVariantNormalizer{
convertAttribute(sourceAttribute: CustomOccAttribute, attributeList: CustomAttribute[]): void{
super.convertAttribute(sourceAttribute, attributeList);
attributeList[attributeList.length - 1].customField = sourceAttribute.customField;
}
}
Extending the original Normalizer seemed like the most promising solution for the time being, and is working quite like intended. So the customField ist being present at this point in time of execution.
Afterwards the OccConfiguratorVariantNormalizer kicks in, which is defining a new Attribute array in convertGroup(), erasing my custom attribute:
convertGroup([...]) {
const attributes: Configurator.Attribute[] = [];
if (source.attributes) {
source.attributes.forEach((sourceAttribute) =>
this.convertAttribute(sourceAttribute, attributes)
);
}
[...]
};
convertAttribute(
sourceAttribute: OccConfigurator.Attribute,
attributeList: Configurator.Attribute[]
): void {
const attribute: Configurator.Attribute = {
name: sourceAttribute.name,
label: sourceAttribute.langDepName,
required: sourceAttribute.required,
uiType: this.convertAttributeType(sourceAttribute.type),
values: [],
groupId: this.getGroupId(sourceAttribute.key, sourceAttribute.name),
userInput: sourceAttribute.formattedValue,
maxlength:
sourceAttribute.maxlength + (sourceAttribute.negativeAllowed ? 1 : 0),
numDecimalPlaces: sourceAttribute.numberScale,
negativeAllowed: sourceAttribute.negativeAllowed,
numTotalLength: sourceAttribute.typeLength,
selectedSingleValue: null,
images: [],
hasConflicts: sourceAttribute?.conflicts?.length > 0 ? true : false,
};
[...]
};
If my custom normalizer was the only one I could imagine it would work, which is why I tried to inject it like this:
{
provide: VARIANT_CONFIGURATOR_NORMALIZER,
useClass: CustomConfiguratorNormalizerService,
multi: false,
}
Throwing me Error: Multi-providers mixed with single providers.
Also, using the documentation from https://sap.github.io/spartacus-docs/connecting-to-other-systems/ I cannot get it to work without extending the original Normalizer, since target will always be undefined
, which probably would not be the case if my custom normalizer came in second.
I feel like this https://github.com/SAP/spartacus/issues/9046 could be related.
Any help very much appreciated :)