Extra data in feeds
Mapping a property as an extraData¶
Sometimes your product/content feed has information you need to present that doesn't fit into the default fields, but you still need to include them. In this particular case they can be stored as ExtraData
Types of extraData¶
| Data Type | Container |
|---|---|
| String, Number, or Boolean | extraData |
| Number (for filtering) | extraDataNumber |
| String Array | extraDataList |
In the following example data, the product feed includes SKU value. SKU exists at the root of the product object, so we map it like we did with the direct child property in the very first example.
{
"type": "product_page",
"id": "{product id}",
"sku": "{product sku}",
"productLink": "<https://example-shop.com/product/party-hat>",
"prices":{
"defaultPrice": 200,
"originalPrice": 180,
}
}
In order to map non-native variables, we use a "container" field named extraData to store the mapped non-native variables.
function transform(product:any): TransformationResult {
return {
...product,
extraData:{
sku: product.sku
}
};
}
When to use extraData and extraDataNumber¶
extraDataNumber is a separate container for handling numbers for filtering like search ranges and comparisons in search results.
In this example we have a size property for a party vest:
{
"type": "product_page",
"id": "{product id}",
"size": 32,
"productLink": "<https://example-shop.com/product/party-vest>",
"prices":{
"defaultPrice": 200,
"originalPrice": 180,
}
}
We could have put this in extraData as well, but if we'd want to make a search range later, we use extraDataNumber instead:
function transform(product:any): TransformationResult {
return {
...product,
extraDataNumber:{
size: product.size
}
};
}
Mapping a property as an extraDataList¶
In this example data, we have a number of color variants, defined in colors:
{
"type": "product_page",
"id": "{product id}",
"colors": ["red","purple","yellow"]
"productLink": "<https://example-shop.com/product/party-hat>",
"prices":{
"defaultPrice": 200,
"originalPrice": 180,
}
}
Because the colors property is a String Array, it is not possible for us to assign it to extraData. We must instead assign it to an extraDataList.
function transform(product:any): TransformationResult {
return {
...product,
extraDataList:{
colors: product.colors
}
};
}
Mapping a single property from an array¶
Let's assume we had some meta data that we wanted to cherry pick from, to set an extraData value:
{
"type": "product_page",
"id": "{product id}",
"metadata": ["red","hat","party"],
"productLink": "<https://example-shop.com/product/party-hat>",
"prices":{
"defaultPrice": 200,
"originalPrice": 180,
}
}
function transform(product:any): TransformationResult {
return {
...product,
extraData:{
type: product.meta[1]
}
};
}
Mapping a property that has special characters or spaces¶
In this example we have an attributes object containing properties with spaces and language specific letters.
This approach is similar to selecting values from an array:
function transform(product:any): TransformationResult {
return {
...product,
extraData: {
shoeBrand: product.attributes["sko mærke"]
}
};
}
Naming extraData keys¶
Keys in extraData, extraDataNumber and extraDataList can only contain the letters a-z and A-Z, the digits 0-9 and _, and can't start with a digit. As a pattern: [a-zA-Z_][a-zA-Z0-9_]*. So -, ., spaces and letters such as æ are out. The rule covers auto mapped keys too.
A key that breaks the rule is dropped. The product is still saved, and the feed run reports Invalid extraData property name: {key} as a problem.
In this example the feed has keys that start with a digit or contain - and .:
{
/* data from previous examples... */
"5euro": "true",
"0-12months": "true",
"1.5-3years": "false"
}
Rename them in the transform. Start with a word and spell out the rest:
const renamedKeys = {
"5euro": "euro5",
"0-12months": "age0to12months",
"1.5-3years": "age1_5to3years"
};
function transform(product:any): TransformationResult {
const result = {...product, extraData: {}};
for (const [feedKey, extraDataKey] of Object.entries(renamedKeys)) {
result.extraData[extraDataKey] = product[feedKey];
delete result[feedKey];
}
return result;
}
The delete matters. Without it, ...product auto maps 5euro as well, and the run reports it.