Skip to content

Commit

Permalink
fix(atomic): remove product currency glitch on render (#4408)
Browse files Browse the repository at this point in the history
Remove `<atomic-product-numeric-field-value>` component from
`<atomic-product-price>` and format the price with the currency directly
on the component.

Also, moved reusable code in utils/

https://coveord.atlassian.net/browse/KIT-3476
  • Loading branch information
y-lakhdar authored Sep 27, 2024
1 parent 483ab44 commit ff39242
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Product, ProductTemplatesHelpers} from '@coveo/headless/commerce';
import {Product} from '@coveo/headless/commerce';
import {Component, Prop, Element, State, Listen} from '@stencil/core';
import {Bindings} from '../../../../components';
import {InitializeBindings} from '../../../../utils/initialization-utils';
Expand All @@ -7,6 +7,7 @@ import {
NumberFormatter,
} from '../../../common/formats/format-common';
import {ProductContext} from '../product-template-decorators';
import {parseValue} from '../product-utils';

/**
* @alpha
Expand Down Expand Up @@ -43,24 +44,6 @@ export class AtomicProductNumber {
this.formatter = event.detail;
}

private parseValue() {
const value = ProductTemplatesHelpers.getProductProperty(
this.product,
this.field
);
if (value === null) {
return null;
}
const valueAsNumber = parseFloat(`${value}`);
if (Number.isNaN(valueAsNumber)) {
this.error = new Error(
`Could not parse "${value}" from field "${this.field}" as a number.`
);
return null;
}
return valueAsNumber;
}

private formatValue(value: number) {
try {
return this.formatter(value, this.bindings.i18n.languages as string[]);
Expand All @@ -71,7 +54,7 @@ export class AtomicProductNumber {
}

private updateValueToDisplay() {
const value = this.parseValue();
const value = parseValue(this.product, this.field);
if (value !== null) {
this.valueToDisplay = this.formatValue(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import {
InitializableComponent,
InitializeBindings,
} from '../../../../utils/initialization-utils';
import {defaultCurrencyFormatter} from '../../../common/formats/format-common';
import {CommerceBindings} from '../../atomic-commerce-interface/atomic-commerce-interface';
import {ProductContext} from '../product-template-decorators';
import {parseValue} from '../product-utils';

/**
* @alpha
Expand All @@ -35,31 +37,61 @@ export class AtomicProductPrice
this.context = buildContext(this.bindings.engine);
}

public render() {
const hasPromotionalPrice =
private formatValue(value: number) {
try {
const {currency} = this.contextState;
const formatter = defaultCurrencyFormatter(currency);
return formatter(value, this.bindings.i18n.languages as string[]);
} catch (error) {
this.error = error as Error;
return value.toString();
}
}

private parse(field: string) {
try {
return parseValue(this.product, field);
} catch (error) {
this.error = error as Error;
return null;
}
}

private getFormattedValue(field: string) {
const value = this.parse(field);
if (value !== null) {
return this.formatValue(value);
}
}

private get hasPromotionalPrice() {
return (
this.product.ec_promo_price !== null &&
this.product.ec_price !== null &&
this.product.ec_promo_price < this.product.ec_price;
this.product.ec_promo_price < this.product.ec_price
);
}

public render() {
const mainPrice = this.getFormattedValue(
this.hasPromotionalPrice ? 'ec_promo_price' : 'ec_price'
);

const {currency} = this.contextState;
const originalPrice = this.hasPromotionalPrice
? this.getFormattedValue('ec_price')
: null;

return (
<div class="flex flex-wrap">
<atomic-product-numeric-field-value
class={`mx-1 truncate break-keep ${hasPromotionalPrice && 'text-error'}`}
field={hasPromotionalPrice ? 'ec_promo_price' : 'ec_price'}
<div
class={`mx-1 truncate break-keep ${this.hasPromotionalPrice && 'text-error'}`}
>
<atomic-format-currency currency={currency}></atomic-format-currency>
</atomic-product-numeric-field-value>
{hasPromotionalPrice && (
<atomic-product-numeric-field-value
class="mx-1 truncate break-keep text-xl line-through"
field="ec_price"
>
<atomic-format-currency
currency={currency}
></atomic-format-currency>
</atomic-product-numeric-field-value>
{mainPrice}
</div>
{originalPrice && (
<div class="mx-1 truncate break-keep text-xl line-through">
{originalPrice}
</div>
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class FieldValueIsNaNError extends Error {
constructor(field: string, value?: {}) {
super(`Could not parse "${value}" from field "${field}" as a number.`);
this.name = 'FieldValueIsNaNError';
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import {Product, ProductTemplatesHelpers} from '@coveo/headless/commerce';
import {readFromObject} from '../../../utils/object-utils';
import {CommerceBindings} from '../atomic-commerce-interface/atomic-commerce-interface';
import {FieldValueIsNaNError} from './error';

export function parseValue(product: Product, field: string) {
const value = ProductTemplatesHelpers.getProductProperty(product, field);
if (value === null) {
return null;
}
const valueAsNumber = parseFloat(`${value}`);
if (Number.isNaN(valueAsNumber)) {
throw new FieldValueIsNaNError(field, value);
}
return valueAsNumber;
}

export function getStringValueFromProductOrNull(
product: Product,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {FunctionalComponent, h, VNode} from '@stencil/core';
import {i18n} from 'i18next';
import {FieldValueIsNaNError} from '../../commerce/product-template-components/error';

interface RatingProps {
i18n: i18n;
Expand Down Expand Up @@ -72,9 +73,7 @@ export const computeNumberOfStars = (
}
const valueAsNumber = parseFloat(`${value}`);
if (Number.isNaN(valueAsNumber)) {
throw new Error(
`Could not parse "${value}" from field "${field}" as a number.`
);
throw new FieldValueIsNaNError(field, value);
}
return valueAsNumber;
};
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ <h1>Surf accessories</h1>
<atomic-product-rating field="ec_rating"></atomic-product-rating>
</atomic-product-section-metadata>
<atomic-product-section-emphasized>
<atomic-product-price currency="USD" class="text-2xl"></atomic-product-price>
<atomic-product-price class="text-2xl"></atomic-product-price>
</atomic-product-section-emphasized>
<atomic-product-section-description>
<atomic-product-description></atomic-product-description>
Expand Down

0 comments on commit ff39242

Please sign in to comment.