Help with Related Items Code / SDK error

Hi, I am looking for help with my code for adding a related items repeater to my store’s product page.

I have basically followed this tutorial:

In my case, ‘productA’ and ‘productB’ are ‘petrol’ and ‘diesel’ .
If the name of the product includes ‘diesel’ then I want to display related products from the ‘petrol’ list, and vice versa.
So as I understand it, if the product displayed on the product page is one of those in the ‘diesel’ column, then the repeater should show the ‘petrol’ products.

I didn’t need to display products that are related by price, so I left that section out.

When I preview the code, I get the following error:
Wix code SDK error: Each item in the items array must have a member named _id which contains a unique value identifying the item.
It says the error is at line 48, which is this line: $w ( “#relatedItemsRepeater” ). data = relatedProducts ;

I don’t know how to fix it so I would appreciate any help.

disclaimer
I know nothing about coding and have literally copied the tutorial pretty much exactly so please be gentle!!

edit
It would seem others have also had similar problems (I searched) but no answers were forthcoming.

Thank you
Cat

Here is the code:

import wixData from ‘wix-data’ ;
import wixLocation from ‘wix-location’ ;

$w . onReady ( function () {
loadRelatedProducts ();
});

async function loadRelatedProducts () {
let product = await $w ( ‘#productPage’ ). getProduct ();
let relatedProductResults = await Promise . all ([
relatedProductsByName ( product )
]);

if  ( relatedProductResults [ 0 ]. length  >  0 ) 
    showRelatedProducts ( relatedProductResults [ 0 ]); 
**else** 
    showRelatedProducts ( relatedProductResults [ 1 ]); 

};

async function relatedProductsByName ( product ) {
let productId = product . _id ;

// find related products by name table 
let  relatedByName  =  **await**  Promise . all ([ 
    wixData . query ( 'relatedProducts' ) 
    . eq ( 'diesel' ,  productId ) 
    . include ( 'petrol' ) 
    . find (), 
    wixData . query ( 'relatedProducts' ) 
    . eq ( 'petrol' ,  productId ) 
    . include ( 'diesel' ) 
    . find () 
]); 

let  relatedProducts  = [ 
    ... relatedByName [ 0 ]. items . map ( _  =>  _ . diesel ), 
    ... relatedByName [ 1 ]. items . map ( _  =>  _ . petrol ) 
]; 
**return**  relatedProducts ; 

};

function showRelatedProducts ( relatedProducts ) {
if ( relatedProducts . length > 0 ) {
relatedProducts . splice ( 4 , relatedProducts . length );
$w ( ‘#relatedItemsRepeater’ ). onItemReady ( relatedItemReady );
$w ( “#relatedItemsRepeater” ). data = relatedProducts ;
$w ( “#relatedItems” ). expand ();
} else {
$w ( “#relatedItems” ). collapse ();
}
};

function relatedItemReady ( $w , product ) {
$w ( “#productImage” ). src = product . mainMedia ;
$w ( “#productName” ). text = product . name ;
$w ( “#productPrice” ). text = product . formattedPrice ;
$w ( ‘#productImage’ ). onClick (() => {
wixLocation . to ( product . productPageUrl );
});
};

I’ve asked Wix support for help but no joy yet, so if anyone has any ideas I would really appreciate help!

Well… seems there is tumbleweed everywhere.

I have managed to get my code to the point where it shows one related item. It really needs to show all of the related items, so if anyone can tell me what I am missing please do!

Meanwhile, this code worked to show 1 product. If it helps anyone else trying to learn, I’ve added what it does in the // thingys.

// find related products code //

//-------------Imports-------------//

import wixData from ‘wix-data’ ;
import wixLocation from ‘wix-location’ ;

//-------------Page Setup-------------//

$w . onReady ( async function () {

// Get the current product’s data.
let product = await $w ( ‘#productPage’ ). getProduct ();

// Load the products that are related to the currently displayed product using the loadRelatedProducts() function.
loadRelatedProducts ( product );

wixLocation . onChange ( async ( location ) => {
let product = await $w ( ‘#productPage’ ). getProduct ();
loadRelatedProducts ( product );
});
});

// Load the products that are related to the currently displayed product.
async function loadRelatedProducts ( product ) {

// Get the related product results using the relatedProductsByFuel() function.
let relatedProductResults = await Promise . all ([
relatedProductsByFuel ( product )
]);

// If there are related products found in the “related-products” collection:
if ( relatedProductResults [ 0 ]. length > 0 )

// Show the related products from the collection.
showRelatedProducts ( relatedProductResults [ 0 ]);

// If there are no related products found in the “related-products” collection:
else

// Fallback to showing the related products by price.
showRelatedProducts ( relatedProductResults [ 1 ]);
}

// Get related products based on the relations set in the “relatedProducts” collection.
async function relatedProductsByFuel ( product ) {

// Get the current product’s ID.
let productId = product . _id ;

// Find related products by querying for related products in both relation directions.
let relatedByFuel = await Promise . all ([
wixData . query ( ‘relatedProducts’ )
. eq ( ‘diesel’ , productId )
. include ( ‘petrol’ )
. find (),
wixData . query ( ‘relatedProducts’ )
. eq ( ‘petrol’ , productId )
. include ( ‘diesel’ )
. find ()
]);

// Merge related products found from both sides of the relationship collection.
let relatedProducts = [
… relatedByFuel [ 0 ]. items . map ( _ => _ . petrol ),
… relatedByFuel [ 1 ]. items . map ( _ => _ . diesel )
];

//Return the related products found in the collection.
return relatedProducts ;
};

// Show the related products on the page.
function showRelatedProducts ( relatedProducts ) {
if ( relatedProducts [ 0 ] !== undefined ) {

// Remove all but the first four related items.
relatedProducts . splice ( 4 , relatedProducts . length );

// Set the function that runs when the related items repeater data is loaded to be relatedItemReady().
$w ( ‘#relatedItemsRepeater’ ). onItemReady ( relatedItemReady );
$w ( “#relatedItemsRepeater” ). data = relatedProducts ;

}
// Set up the related items repeater as its data is loaded
function relatedItemReady ( $item , product ) {

// Populate the repeater elements from the item data.
$item ( “#productImage” ). src = product . mainMedia ;
$item ( “#productName” ). text = product . name ;
$item ( “#productPrice” ). text = product . formattedPrice ;

// Set the action that occurs when the image is clicked
$item ( ‘#productImage’ ). onClick (() => {
wixLocation . to ( product . productPageUrl );
});
};
}