Need help with adding reviews section on dynamic page

I have watched almost every video & read as many articles as possible on the topic of Dynmic pages - Reviews/Comment sections. Could someone please help me understand where I went wrong?

The reviews can be manually typed in but the button going to the Light Box isn’t working. I believe this is something to do with the productId not connecting.

For some reason I keep getting an error:
Error: Cannot read properties of null (reading ‘_id’) Line 35

Also, when I click on the Leave a review button or comment button it just gives me the same error but goes to Line 123 instead.

I copied pretty much everything from the Wix example Here:

Product Reviews | Velo by Wix Examples | Wix.com

Still not working. I’ve checked all of the IDs multiple times and I don’t see anything off.

$w.onReady( () => {
  $w("#dynamicDataset").onReady( () => {
    const itemUrl = $w('#dynamicDataset').getCurrentItem().url;
    $w('#html1').src = itemUrl;
  } );
} );
//-------------Imports-------------//

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

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

// Current product.
let product; 

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

$w.onReady(async function () {
    // Set the global product variable to the currently displayed product.
    product = await $w('#dynamicDataset').getCurrentItem(); 
    // Load the current product's reviews using the initReviews() function.
    initReviews(); 
      wixLocation.onChange(async (location) => {
    product = await $w('#dynamicDataset').getCurrentItem();
    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 ratings = $w('#generalRatings');
        // 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} % would recommend`; 
        // 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 = 'There are no reviews yet'; 
    }
    // 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 = 'I recommend this product.'; 
    // If the reviewer does not recommend the item:
    } else {
        // Set the "don't recomend" text.
        $w('#recommendation').text = "I don't recommend this product.";
    }

    // 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('#oneRating').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.toLocaleString();
}

//-------------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 = {
        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.
    setTimeout(() => {
        loadStatistics();
    }, 2000);
    // Show a thank you message.
    $w('#thankYouMessage').show();
}

In both of your initial screenshots with the line errors, I’m not seeing how the product is even getting there.

I would console.log(product) and see if you even have an object.

IN the first one, I don’t see where you pass product to that function

And in the second (line 123) again, I don’t see how product gets there so it may not be that the _id is null, it may be that you don’t have anythign there at all. Not sure, but I would suggest debugging at the level of the product object at each place you use it

@amandam Displays an “undefined” on the Developer Console when posting the console.log(product). So… No object.

Then when I opened the Console.

I figured the async function is supposed to pass the productId.

Originally the product = await $w ( ‘#dynamicDataset’ ). getCurrentItem (); was " ( ‘productId’ , product . _id ))". Instead of the getCurrentItem().

Oh nooo! Don’t cry lol. This is good! Now you know where to start looking.

So, let me make sure I understand…

At any point do you have code that is successfully retrieving a product object? That is the first problem you will want to work on solving.