diff --git a/.changeset/wet-dogs-warn.md b/.changeset/wet-dogs-warn.md new file mode 100644 index 0000000..9b377f8 --- /dev/null +++ b/.changeset/wet-dogs-warn.md @@ -0,0 +1,5 @@ +--- +"saleor-app-search": patch +--- + +Fix missing attribute values in products diff --git a/apps/search/src/lib/algolia/algoliaUtils.ts b/apps/search/src/lib/algolia/algoliaUtils.ts index 2a49b10..9509f17 100644 --- a/apps/search/src/lib/algolia/algoliaUtils.ts +++ b/apps/search/src/lib/algolia/algoliaUtils.ts @@ -1,4 +1,7 @@ -import { ProductVariantWebhookPayloadFragment } from "../../../generated/graphql"; +import { + ProductAttributesDataFragment, + ProductVariantWebhookPayloadFragment, +} from "../../../generated/graphql"; import { isNotNil } from "../isNotNil"; type PartialChannelListing = { @@ -55,6 +58,22 @@ export function formatMetadata({ product }: ProductVariantWebhookPayloadFragment export type AlgoliaObject = ReturnType; +/** + * Returns object with a key being attribute name and value of all attribute values + * separated by comma. If no value is selected, an empty string will be used instead. + */ +const mapSelectedAttributesToRecord = (attr: ProductAttributesDataFragment) => { + if (!attr.attribute.name?.length) { + return undefined; + } + + const filteredValues = attr.values.filter((v) => !!v.name?.length); + + return { + [attr.attribute.name]: filteredValues.map((v) => v.name).join(", ") || "", + }; +}; + export function productAndVariantToAlgolia({ variant, channel, @@ -65,10 +84,24 @@ export function productAndVariantToAlgolia({ const product = variant.product; const attributes = { ...product.attributes.reduce((acc, attr, idx) => { - return { ...acc, [attr.attribute.name ?? ""]: attr.values[idx]?.name ?? "" }; + const preparedAttr = mapSelectedAttributesToRecord(attr); + if (!preparedAttr) { + return acc; + } + return { + ...acc, + ...preparedAttr, + }; }, {}), ...variant.attributes.reduce((acc, attr, idx) => { - return { ...acc, [attr.attribute.name ?? ""]: attr.values[idx]?.name ?? "" }; + const preparedAttr = mapSelectedAttributesToRecord(attr); + if (!preparedAttr) { + return acc; + } + return { + ...acc, + ...preparedAttr, + }; }, {}), };