UI Extension — Recipes
Custom API
By specifying api="custom"
, you can override the data fetching behavior. In the following example, you can combine the results from two different Miso APIs (code example):
const model = new MisoClient.ui.models.classes.MisoListModel({
api: 'custom',
fetch: fetch
});
async function fetch({ payload, client }) {
// call both API in bulk mode, so they are combined into a single request
const [ response0, response1 ] = await Promise.all([
client.api.recommendation.productToProducts({ product_id: '...', fl: ['*'], rows: 4 }, { bulk: true }),
client.api.recommendation.userToProducts({ fl: ['*'], rows: 4 }, { bulk: true })
]);
// combine the retrieved products starting with ones from productToProducts() with list size trimmed to 4
const products = [...response0.products, ...response1.products].slice(0, 4);
return {
...response0,
products: products,
};
}
Deduplication
If you want to deduplicate the results across multiple recommendation sections in one page, you can achieve it using the model’s transform
setting (code example).
Given two <miso-list>
in the page, each of which shows 4 products:
<miso-list id="x" class="recommendation" auto-model="false" on:start="load">...</miso-list>
<miso-list id="y" class="recommendation" auto-model="false" on:start="load">...</miso-list>
Keep track of shown items and filter out redundant ones:
const shownProductIds = new Set();
function transform(data) {
// filter out already shown products and trim size to 4
const items = data.items
.filter(item => !shownProductIds.has(item.product_group_id))
.slice(0, 4);
// keep track of which products are shown
for (const item of items) {
shownProductIds.add(item.product_id);
}
return Object.assign({}, data, { items: items });
}
const MisoListModel = MisoClient.ui.models.classes.MisoListModel;
const misoListX = document.querySelector('#x');
const misoListY = document.querySelector('#x');
misoListX.model = new MisoListModel({
api: 'user_to_products',
payload: {
// ...,
rows: 8 // in the worst case, 4 of them are filtered out
},
transform: transform
});
misoListY.model = new MisoListModel({
api: 'product_to_products',
payload: {
// ...,
rows: 8
},
transform: transform
});