Since Wix/Velo team have been unable to guide me on how to achieve the right coding to avoid getting product ratings and reviews duplicated on each and every product of my Wix store; and I have spend SO MANY hours trying to work out the solution; I will share the code with you guys - NOTHING NEW. Wix/Velo are probably are the worst customer service I’ve ever dealt with when it comes to website building
THE EXAMPLE TEMPLATE HAS MISTAKES -as most of the examples on this site
Anyway; I’m sharing my code with you guys since I have seen this is an issue a lot of you are also facing when building their site. So, first thing is to put all your onReady items together. One per page. Nobody states anything on the forum on how to do that; but it’s important to consolidate them in order to avoid inconsistency which will lead to errors.
Here is the right code
import wixData from ‘wix-data’ ;
import wixUsers from ‘wix-users’ ;
import wixLocation from ‘wix-location’ ;
import wixWindow from ‘wix-window’ ;
import {local, session} from ‘wix-storage’ ;
// Current product.
let product;
//-------------Page Setup-------------//
$w.onReady( async function () {
product = await $w( ‘#productPage1’ ).getProduct();
initReviews();
wixLocation.onChange( async (location) => {
product = await $w( ‘#productPage1’ ).getProduct();
initReviews();
})
// Loads the current product’s reviews.
async function initReviews() {
// Filter the “Reviews” dataset to contain only the reviews on the currently displayed product.
await $w( ‘#Reviews’ ).setFilter(wixData.filter().eq( ‘productId’ , product._id));
// Show the reviews after the filter was set and applied on the dataset
showReviews();
// Load the current product’s statistics using the loadStatistics() function.
loadStatistics();
}
// Load the current product’s statistics.
async function loadStatistics() {
// Get the statistics data based on the current product’s ID.
const stats = await wixData.get( ‘review-stats’ , product._id);
// If statistics data for the product was found:
if (stats) {
// Compute the product’s average rating by dividing the total points by the number of ratings.
let avgRating = (Math.round(stats.rating * 10 / stats.count) / 10 );
// Compute the percentage of reviewers that recommend the product.
let percentRecommended = Math.round(stats.recommended / stats.count * 100 );
// Get the ratings element.
let rating = $w( ‘#generalRatings’ );
// Set the ratings element’s average rating to the value calculated above.
rating.rating = avgRating;
// Set the ratings element’s number of ratings to the count value from the statistics data.
rating.numRatings = stats.count;
// Set the text for the recommended percentage element.
$w( ‘#recoPercent’ ).text = ${percentRecommended} % lo recomiendarían
;
// Show the ratings element.
$w( ‘#generalRatings’ ).show();
// If there is no statistics data for the product:
} else {
// Set the text for the recommended percentage element to reflect the fact that there are no reviews.
$w( ‘#recoPercent’ ).text = ‘’ ;
//THIS LINE IS NOT IN THE EXAMPLE TEMPLATE. DO NOT FORGET IT
$w( ‘#generalRatings’ ).hide();
}
// Show the recommended percentage element only after it is populated to avoid flickering.
$w( ‘#recoPercent’ ).show();
}
//-------------Repeater Setup -------------//
// Set up each item in the reivews repeater as it is loaded.
export function reviewsRepeater_itemReady($w, itemData, index) {
// If the reviewer recommends the item:
if (itemData.recommends) {
// Set the "recommend text.
$w( ‘#recommendation’ ).text = ‘Sí, lo recomendaría.’ ;
// If the reviewer does not recommend the item:
} else {
// Set the “don’t recomend” text.
$w( ‘#recommendation’ ).text = “No lo recomendaría.” ;
}
// If a photo was uploaded for the review:
if (itemData.photo) {
// Set the image URL from the item data.
$w( ‘#reviewImage’ ).src = itemData.photo;
// Expand the image.
$w( ‘#reviewImage’ ).expand();
}
// Set the ratings element’s rating value.
$w( '#Rating' ).rating = itemData.rating;
// Get the date that the review was entered.
let date = itemData._createdDate;
// Format the date according to the date format settings on the user’s computer.
$w( ‘#submissionTime’ ).text = date.toLocaleDateString();
}
//-------------Data Setup -------------//
// Perform some setup when the dataset filter was completed.
export function showReviews() {
// If at least one review has been submitted:
if ($w( ‘#Reviews’ ).getTotalCount() > 0 ) {
// Expand the strip that displays the reviews.
$w( ‘#reviewsStrip’ ).expand();
// THIS IS OPTIONAL; but here, we’re basically letting the code know how many reviews we want to display on each repeater once the page loads; the less reviews we display; the quicker the page loads
$w( ‘#Reviews’ ).setPageSize( 1 );
// If there are no reviews:
} else {
// Collapse the strip that displays the reviews.
$w( ‘#reviewsStrip’ ).collapse(); //otherwise, hide it
}
}
//-------------Event Handlers -------------//
// Set the action that occurs when a user clicks the “Write a Review” button.
export async function addReview_click(event, $w) {
// Create an object containing the current product’s ID to be sent to the review writing lightbox.
const dataForLightbox = {
productId: product._id
};
// Open the “Review Box” lightbox, send it the object created above, and wait for it to close.
let result = await wixWindow.openLightbox( ‘Review Box’ , dataForLightbox);
// After the review lightbox is closed, refresh the reviews dataset so the new review appears on the page.
$w( ‘#Reviews’ ).refresh();
// Reload the current products statistics to reflect the new rating.
loadStatistics();
// Show a thank you message.
$w( ‘#thankYouMessage’ ).show();
}
// Set the action that occurs when a user clicks the “Load More” text.
export function resultsPages_click(event) {
// Load additional reviews into the reviews repeater.
$w( ‘#Reviews’ ).loadMore()
// This step is also optional / It just tell the repeater how many ratings to display when loadMore button is clicked
$w( ‘#Reviews’ ).setPageSize( 4 );
}
I hope you guys find it useful