Display Average Ratings for each Items on Dynamic Category Page

Hello! I need some help in displaying average ratings for each items on a Dynamic Category page .

I recently followed step by step the Corvid Tutorial to add ratings and reviews to my website. Instead of a Wix store I adapted this slightly to use the feature with dynamic pages.

Now I’m wondering if it’s possible to use the average ratings generated on each individual dynamic page and correctly display them under their corresponding item on the main index .

I currently have the rating images as a placeholder on the main index page, but they are not attached to any data and thus not updating. Is there a way for me to pull the data to get all average ratings to show on the main index page, correctly assigned to each individual item?

If someone can help me by sharing some code that I can put directly on my Dynamic Category Page it would be very appreciated. For information purpose, please find below the code I used for ratings and reviews on Dynamic Item page and that works fine.

Thanks in advance for your help!


// API Reference: https://www.wix.com/velo/reference/api-overview/introduction
// “Hello, World!” Example: https://learn-code.wix.com/en/article/1-hello-world

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

import wixData from 'wix-data';
import wixWindow from 'wix-window';

//-------------Global Variables-------------//

// Current product.
let presta; 

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

$w.onReady(async function() {
 // Set the global product variable to the currently displayed product.
    presta = await $w('#dynamicDataset').getCurrentItem(); 
 // Load the current product's reviews using the initReviews() function.
    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('prestaId', presta._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-stats1', presta._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 ratings = $w("#generalRatings, #ratingsDisplay1");
 // Set the ratings element's average rating to the value calculated above. 
        ratings.rating = avgRating;
 // Set the ratings element's number of ratings to the count value from the statistics data.
        ratings.numRatings = stats.count;
 // Set the text for the recommended percentage element.
        $w('#recoPercent').text = `${percentRecommended} % des mariés nous recommandent`; 
 // Show the ratings element.
        $w('#generalRatings, #ratingsDisplay1').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 = 'Aucun avis pour le moment'; 
    }
 // Show the recommended percentage element only after it is populated to avoid flickering.
    $w('#recoPercent').show(); 
}

//-------------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();
 // 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 = {
        prestaId: presta._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 2', 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 resultsPages1_click(event, $w) {
 // Load additional reviews into the reviews repeater.
    $w('#Reviews').loadMore();
}

I copy paste below some additional information (code, screenshot of the Dynamic Category page) in case someone would kindly help me.


  • Name of the dataset: review-stats1
  • Rating Display element: #ratingsDisplay1
  • Repeater ID: #repeater1


Here is the code I used on my dynamic category page but it doesn’t work properly. The average rating of each items isn’t displayed as it should do.



//-------------Imports-------------//
import wixData from 'wix-data';
import wixWindow from 'wix-window';


$w.onReady(function () {


$w('#dataset1').onReady(async () => {

 $w("#repeater1").onItemReady(($item, itemData, index) => {
 $item("#_id").text = itemData._id;

 async function loadStatistics() {
 const stats = await wixData.get('review-stats1')
 if (stats) {
 let avgRating = (Math.round(stats.rating * 10 / stats.count) / 10);
 let ratings = $w('#ratingsDisplay1');
 ratings.rating = avgRating;
 ratings.numRatings = stats.count;
 $w('#ratingsDisplay1').show();
 } else {
 $w('#recoPercent').text = 'There are no reviews yet';
 }
 $w('#recoPercent').show();
 }
 });
 });
 });

Thanks to anyone who could help me with fixing this issue.

Perhaps this may help you…
https://russian-dima.wixsite.com/meinewebsite/rating-system

@russian-dima Hi thanks @russian-dima ! I already had a look at something quite similar but it’s slightly different from what I would like to do. In your rating system example, there is no repeater element and the average field already exist in your database. In my database I only have 2 fields (total number of ratings and total ratings) so to display the average number of ratings I have to divide the total ratings ( #rating ) by the total number of ratings ( #count ) and display it through a rating display element. Would you have any recommendation to do this?

@nadraultgeoffrey
I will take a look at it tomorrow. Today i am working on own projects :grin:

@russian-dima Ok thanks

@nadraultgeoffrey
Ok, what exactly was here the problem ?

You do not have a field for average ok (why ever).
You want to calculate the avarage, right?

Let us say you have …

numRatings = 44
totalRatings = 159

Now you want to get the averageRating

159/44 = averageRatingLong
averageRatingLong = 3,613636363636364

Then you use —> .parseFloat() & .toFixed()

const newAverageShort = Number.parseFloat(newAverageLong).toFixed(1);

But when i am honest, i do not really understand what is the exact problem ?

@russian-dima Thanks for your help. I think you got what I wanted to do. So could you please tell me where I have to insert this:

const newAverageShort = Number.parseFloat(newAverageLong).toFixed(1);

in the code below to show the average number in my repeater element so that each average number per item will be displayed in my dynamic category page?


//-------------Imports-------------//
import wixData from 'wix-data';
import wixWindow from 'wix-window';


$w.onReady(function () {


$w('#dataset1').onReady(async () => {

 $w("#repeater1").onItemReady(($item, itemData, index) => {
 $item("#_id").text = itemData._id;

 async function loadStatistics() {
 const stats = await wixData.get('review-stats1')
 if (stats) {
 let avgRating = (Math.round(stats.rating * 10 / stats.count) / 10);
 let ratings = $w('#ratingsDisplay1');
 ratings.rating = avgRating;
 ratings.numRatings = stats.count;
 $w('#ratingsDisplay1').show();
 } else {
 $w('#recoPercent').text = 'There are no reviews yet';
 }
 $w('#recoPercent').show();
 }
 });
 });
 });