Hello,
I have implemented the product ratings and reviews to and related products to my product page.
All working great accept one small issue;
- If you follow a product displayed in the Related Items Repeater the ratings and reviews from the originating product a displayed. It is resolved if you refresh but of course can’t leave it like that.
I’m sure there is something simple I can do but can’t figure it.
my code:
//-------------Imports-------------//
import wixData from 'wix-data';
import wixWindow from 'wix-window';
import wixLocation from 'wix-location';
//-------------related products Setup-------------//
$w.onReady(function () {
loadRelatedProducts();
});
async function loadRelatedProducts() {
let product = await $w('#productPage').getProduct();
let relatedProductResults = await Promise.all([
relatedProductsByTable(product),
relatedProductsByPrice(product)
]);
if (relatedProductResults[0].length > 0)
showRelatedProducts(relatedProductResults[0]);
else
showRelatedProducts(relatedProductResults[1]);
}
async function relatedProductsByTable(product) {
let productId = product._id;
let relatedByTable = await Promise.all([
wixData.query('relatedProducts')
.eq('productA', productId)
.include('productB')
.find(),
wixData.query('relatedProducts')
.eq('productB', productId)
.include('productA')
.find()
]);
let relatedProducts = [
...relatedByTable[0].items.map(_ => _.productB),
...relatedByTable[1].items.map(_ => _.productA)
];
return relatedProducts;
}
async function relatedProductsByPrice(product) {
let productId = product._id;
let relatedByPrice = await wixData.query('Stores/Products')
.between('price', product.price * 0.8, product.price * 1.2)
.ne('_id', productId)
.find();
return relatedByPrice.items;
}
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);
});
}
//-------------reviews setup-------------//
let product;
$w.onReady(async function () {
product = await $w('#productPage').getProduct();
initReviews();
});
async function initReviews() {
await $w('#Reviews').setFilter(wixData.filter().eq('productId', product._id));
showReviews();
loadStatistics();
}
async function loadStatistics() {
const stats = await wixData.get('review-stats', product._id);
if (stats) {
let avgRating = (Math.round(stats.rating * 10 / stats.count) / 10);
let percentRecommended = Math.round(stats.recommended / stats.count * 100);
let ratings = $w('#generalRatings');
ratings.rating = avgRating;
ratings.numRatings = stats.count;
$w('#recoPercent').text = `${percentRecommended} % would recommend`;
$w('#generalRatings').show();
} else {
$w('#recoPercent').text = 'There are no reviews yet';
}
$w('#recoPercent').show();
}
export function reviewsRepeater_itemReady($w, itemData, index) {
if (itemData.recommends) {
$w('#recommendation').text = 'I recommend this product.';
} else {
$w('#recommendation').text = "I don't recommend this product.";
}
if (itemData.photo) {
$w('#reviewImage').src = itemData.photo;
$w('#reviewImage').expand();
}
$w('#oneRating').rating = itemData.rating;
let date = itemData._createdDate;
$w('#submissionTime').text = date.toLocaleString();
}
export function showReviews() {
if ($w('#Reviews').getTotalCount() > 0) {
$w('#reviewsStrip').expand();
} else {
$w('#reviewsStrip').collapse();
}
}
export async function addReview_click(event, $w) {
const dataForLightbox = {
productId: product._id
};
let result = await wixWindow.openLightbox('Review Box', dataForLightbox);
$w('#Reviews').refresh();
loadStatistics();
$w('#thankYouMessage').show();
}
export function resultsPages_click(event, $w) {
$w('#Reviews').loadMore();
}