I keep getting these messages on my wishlist page for my website:
Wix code SDK Warning: The src parameter of "productImage" that is passed to the src method cannot be set to null or undefined.
Wix code SDK Warning: The text parameter of "name" that is passed to the text method cannot be set to null or undefined.
Wix code SDK Warning: The text parameter of "price" that is passed to the text method cannot be set to null or undefined.
I've been using the codes in the tutorials to help me as well as the example site but I can't for the life of me figure out what to do. I've been researching and working on this code for OVER A WEEK and nothing has helped. I've underlined it for recognition purposes for anyone who can help but it's obviously not underlined on my site.
This is the section of code that I'm having issues with:
// Set up the wishlist repeater items when the repeater's data is loaded.
function myItemReady($w, wishlistItem){
// Get the wishlist product.
let product = wishlistItem.product;
// Set the repeater's elements using the item data.
$w('#productImage').src = product.mainMedia;
$w('#name').text = product.name;
$w('#price').text = product.formattedPrice;
// Set the action that occurs when the product image is clicked.
$w('#productImage').onClick(() => {
// Navigate to the wishlist item's product page.
wixLocation.to(product.productPageUrl);
});
// Set the action that occurs when the remove item image is clicked to the removeItem() function.
$w('#removeItem').onClick(removeItem(wishlistItem._id));
}
Does anyone have ANY clue on what I need to fix?
Hi Ashley:
poolshark314 is on the right track. What ever you have calling your myItemReady() function is likely to be passing a null argument or the wrong argument.
Lets examine this in a mini tutorial using your code:
function myItemReady($w, wishlistItem){ // Get the wishlist product. let product = wishlistItem.product; // Set the repeater's elements using the item data. $w('#productImage').src = product.mainMedia; $w('#name').text = product.name; $w('#price').text = product.formattedPrice;
The Warning you are getting:
Wix code SDK Warning: The src parameter of "productImage" that is passed to the src method cannot be set to null or undefined.
Is essentially saying:
OK let's reverse through the code.
The assignment that is a problem is this one:
$w('#productImage').src = product.mainMedia
This means that the value of product.mainMedia doesn't exist (is null or undefined). Why would this be the case?
Well either:
the value of product is null or undefined
OR
product exists BUT it doesn't have a property called mainMedia.
QUICK Tutorial:
Many times when we use data collections we have all of the data for an item in what is called an object. This is a container that carries multiple values we need each of which is attached to a name that we call a key. These "key:value" pairs are convenient ways to access the value.
In our example we need to assume that product is an object which is carrying some of these "key:value" pairs and that you think one of them is called mainMedia. So if I were to examine a valid product instance I would see something like this:
let product = { "mainMedia": "an Image URL", "name": "the product name", "formattedPrice": "theFormatted price" ... // other records if any };
If product doesn't contain a "key:value" pair like "mainMedia": "an Image URL" then product.mainMedia gives us a null value. null tells us that javascript was sent on a wild goose chase and found nothing!
OK So now we have to look at product to see if it could be the problem. This is the code that gives us our product value:
let product = wishlistItem.product;
Oh guess what another object assignment.
We are not getting an error with this assignment why is that? Well it is perfectly legal to give a new variable (created using let or var) a null value. So this means that:
wishlistItem could be null
OR
there is no "key:value" pair contained in wishlistItem
We now have a mystery that we need to solve. Some where in your code a bad value is being set and we need to figure out where that bad value is coming from to fix the problem. As poolshark314 points out it is highly likely that the problem has nothing to do with your myItemReady() function but the code that calls it :-).
The way we figure that out is by using some console.log() calls. These print the values of the variables at key points in our code to tell us what the values of the dat are as we head towards the problem area. With this data we can (hopefully) get rid of the bad (buggy) code.
So key points to look at values are - always - when a function is called (to see if we got the value we were expecting. So since we are expecting an object we need to use a JSON call to see the contents reliably. The call you need looks like this:
function myItemReady($w, wishlistItem){ // Check our argument - stringify makes sure the object can be // Printed. We also check for a null value and say that is what we found console.log((wishlistItem ? JSON.stringify(wishlistItem): "wishlist is NULL!")); // Get the wishlist product. let product = wishlistItem.product;
The other thing we need to check (if wishlistItem is valid) is what product contains. You should see product in the console.log() output above. This is simply double checking things:
// Get the wishlist product. let product = wishlistItem.product; console.log((product ? JSON.stringify(product): "product is NULL!"));
Now you have this you might be able to figure the rest out. If not we will need to see ALL of your code and have more context for the page.
Also if you post the URL for your page we can given even more help ;-)
Steve
Hi Rudi:
I have had a look at your site and have a better idea of the problem you are dealing with. The problem that you have is in the way you have configured your Data Collection.
There are three ways that you can reference a row in another Data Collection using Wix Code.
Using a text type field to hold the ID (_id) of the referenced row of the other Data Collection
Using a single reference type field to link the ID (_id) of the referenced row of the other collection
Using a multiple reference type field to link one or more IDs (_id) of referenced rows of the other collection.
The reason why your wishList isn't working is because you have configure the WishList Data Collection to use multiple References for the Product reference:
If you review the original Article that you used to create the Wishlist in the first place the reference field was NOT set to Multiple Items.
NOTE: The text states "Each item in the collection associates a member's ID with a product they selected to add to their wishlist". It doesn't state "Each item in the collection associates a member's ID with all of the products they selected to add to their wishlist". Essentially you should only have one record (row) per wishlist item.
OK why is this important?
Well if the data collection had been configured correctly then your original problem would not have manifested itself and your original code would likely have worked. However, because you have selected the multiple-items option you have to use a completely different API to save and retrieve the reference items. As a result this code:
let wishListResult = await wixData.query("Wishlist") .eq("product", product._id) .eq("userId", user.id) .find();
and this code:
let result = await wixData.insert("Wishlist", wishListItem);
do not perform as expected. In fact the insert statement above results in the following Data Collection records being saved:
Because there are records for the user id, but the product references are empty, you are getting the errors in the Wishlist page that brought us to this point :-). So when a record is loaded the product field is empty and therefore the statement
let product = wishlistItem.product;
Will alway return null for the product variable.
OK that's the problem explained. Now how to fix it? Basically you unselect the Multiple Items in the Wishlist Data Collection and voila - your code starts to work ;-).
This thread has uncovered a bug that I will research with the product team. Basically you should get an error if a value passed to the insert function isn't inserted into the data collection. You shouldn't have a new record missing the key data you wanted to save :-)
Steve
Hi Rudi - OK I overlooked that your wixLocation.to() call is in an onClick handler. This needs to see the productRecord returned in your wixData.get() then() handler. A simple solution is to move the $w(‘#productImage’).onClick handler immediately below the line $w(‘#price’).text = productRecord.formattedPrice; Steve
Hi Rudi Again I suggest you take a look at the database documentation. On the menu above the data collection columns you will see an option marked “Visible Fields”. When a data collection is created there are four fields that are ALWAYS created and they are: ID(_id), Created Date(createdDate), Update Date(updateDate) and Owner(owner). The name in parenthesis is the fieldName used in code. These fields are not visible by default in the Data Collection view. You have to enable the ones you want to see. They are in the data collection just not shown in the Editor screen. To see them you click on “Visible Fields” and click the check box next to the field you want to see. You can also hide fields you don’t want to see. :-)
.
Hi Rudi Two questions. 1. What is the value of wishlistItem.product? It should be a product ‘_id’. That is what the wixData.get() expects. 2. Is the get() returning the object you expect? If productRecord is null or empty then the assignment to $w(‘#productImage’).src is not a URL (string) so will cause your failure. Also you pass $item I to the handler but don’t use it. You need to use $item(‘#productImage’).src and not $w(‘#productImage’).src :-). The same goes for the other repeater elements. Cheers Steve
I got this message error when i click the product.
Wix code SDK error: The url parameter that is passed to the to method cannot be set to the value . It must be of type string.
Dear Steve,
Thank you so much for help. I try the code here : and it works i can remove item but only one problem : i can't add product from product page to to Mywishlist. i think not connect but dont know which code is wrong. Help me please :(
Here is Mywishlist code that works:
// For full API documentation, including code examples, visit http://wix.to/94BuAAs //-------------Imports-------------// // Import the wix-data module for working with queries. import wixData from 'wix-data'; // Import the wix-users module for working with users. import wixUsers from 'wix-users'; // Import the wix-location module for navigating to pages. import wixLocation from 'wix-location'; //-------------Page Setup-------------// $w.onReady(async function () { // Get the current user. let user = wixUsers.currentUser; // If the current user is logged in: if(user.loggedIn) // Load the user's wishlist using the loadWishlist() function. return loadWishlist(); // If the current user is not logged in: // Collapse the wishlist. $w('#wishlist').collapse(); // Expand the empty whishlist. $w('#emptyWishlist').expand(); }); // Load and display the current user's wishlist. async function loadWishlist(){ // Get the current user. let user = wixUsers.currentUser; // Query the "Wishlist" collection for all wishlist items belonging to the current user. let wishlistResult = await wixData.query("Wishlist") .eq("userId", user.id) .include('product') .find() // If any wishlist items were found: if (wishlistResult.length > 0) { // Expand the wishlist. $w("#wishlist").expand(); // Collapse the empty wishlist. $w("#emptyWishlist").collapse(); // Set the wishlist repeater's data. $w("#wishlist").data = wishlistResult.items; // Set the action that occurs when the wishlist repeater items are loaded to the myItemReady() function. $w('#wishlist').onItemReady(myItemReady); } // If no wishlist items were found: else { // Collapse the wishlist. $w("#wishlist").collapse(); // Expand the empty wishlist. $w("#emptyWishlist").expand(); } } // Set up the wishlist repeater items when the repeater's data is loaded. function myItemReady($item, wishlistItem){ // Get the wishlist product. let product = wishlistItem.product; // Get the product information from the product database wixData.get("Stores/Products", product) .then((productRecord) => { // Set the repeater's elements using the item data. $w('#productImage').src = productRecord.mainMedia; $w('#name').text = productRecord.name; $w('#price').text = productRecord.formattedPrice; }); // Set the action that occurs when the product image is clicked. $w('#productImage').onClick(() => { // Navigate to the wishlist item's product page. wixLocation.to(product.productPageUrl); }); // Set the action that occurs when the remove item image is clicked to the removeItem() function. $w('#removeItem').onClick(removeItem(wishlistItem._id)); } // Remove an item from the user's wishlist. function removeItem(id) { return async function() { // Remove the item with the specified ID from the "Wishlist" collection. await wixData.remove('Wishlist', id); // Reload the wishlist to reflect the removed item. loadWishlist(); } }
But there is error on product page, i can't add any product from product page into Mywhistlist.
Here is the code :
//-------------Imports-------------// // Import the wix-data module for working with queries. import wixData from 'wix-data'; // Import the wix-users module for working with users. import wixUsers from 'wix-users'; //-------------Global Variables-------------// // Current product. let product; // Current user. let user = wixUsers.currentUser; //-------------Page Setup-------------// $w.onReady(async function () { // Get the currently displayed product. product = await $w('#productPage1').getProduct(); // Check if the current product is in the wishlist and act accordingly. checkWishlist(); // Set the action that occurs when the login message is clicked to be the loginMessageClick() function. $w('#loginMessage').onClick(loginMessageClick); }); // Check if the current product is in the wishlist and act accordingly. async function checkWishlist() { // If the current user is logged in: if (wixUsers.currentUser.loggedIn) { // Query the "Wishlist" collection to find if the product was already added to the user's wishlist. let wishListResult = await wixData.query("Wishlist") .eq("product", product._id) .eq("userId", user.id) .find(); // If the product was already added to the user's wishlist: if(wishListResult.items.length > 0) // Show the "inWishList" image with a fade effect. $w('#inWishList').show('fade', {duration: 100}); // If the product was not yet added to the user's wishlist: else // Show the "notInWishList" image with a fade effect. $w('#notInWishList').show('fade', {duration: 100}); } // If the current user is not logged in: else { // Show the "notInWishList" image with a fade effect. $w('#notInWishList').show('fade', {duration: 100}); } } //-------------Event Handlers-------------// // Set the action that occurs when the "inWishList" image is clicked. export function inWishList_click(event, $w) { // If the current user is logged in: if (user.loggedIn) // Remove the current product from the wishlist. removeFromWishlist(); } // Set the action that occurs when the "notInWishList" image is clicked. export function notInWishList_click(event, $w) { // If the current user is logged in: if (user.loggedIn) // Add the current product to the wishlist. addToWishlist() // If the current user is not logged in: else // Show the login message. $w('#loginMessage').show(); } // Set the action that occurs when the login message is clicked. async function loginMessageClick() { // Set the login options. let options = {"mode": "login"}; // Hide the login message. $w('#loginMessage').hide(); // Prompt the user to login using the options created above. await wixUsers.promptLogin(options); } //-------------Wishlist Functionality-------------// // Add the current product to the current user's wishlist and update the page accordingly. async function addToWishlist() { // Create the wishlist item relating the current product to the current user. let wishListItem = { product: product._id, userId: user.id }; // Hide the "notInWishList" image with a fade effect. $w('#notInWishList').hide('fade', {duration: 100}); // Show the "inWishList" image with a fade effect. $w('#inWishList').show('fade', {duration: 100}); // Insert the item created above into the "Wishlist" collection. let result = await wixData.insert("Wishlist", wishListItem); } // Remove the current product to the current user's wishlist and update the page accordingly. async function removeFromWishlist() { // Query the "Wishlist" collection to find the wishlist item corresponding to the current product and current user. let wishListResult = await wixData.query("Wishlist") .eq("product", product._id) .eq("userId", user.id) .find(); // If a wishlist item was found: if (wishListResult.length > 0) { // Show the "notInWishList" image with a fade effect. $w('#notInWishList').show('fade', {duration: 100}); // Hide the "inWishList" image with a fade effect. $w('#inWishList').hide('fade', {duration: 100}); // Remove the wishlist item from the "Wishlist" collection. await wixData.remove("Wishlist", wishListResult.items[0]._id) } }
Try changing your myItemReady function to use a different scope variable instead of $w. $w is defined in the outer scope and may cause problems. Check out the documentation: https://www.wix.com/code/reference/$w.Repeater.html#onItemReady I would use $item instead of $w. function myItemReady($item, wishlistItem, index) { ... Cheers Steve
Hi Steve, i create wishlist on dummies web and it is work. https://eira82.wixsite.com/alamliving
following the tutorial https://support.wix.com/en/article/wix-code-how-to-add-a-wishlist-to-a-wix-stores-site#step-4-create-the-add-to-wishlist-function-on-the-product-page-1
Problem in this web https://rudi006.wixsite.com/alamliving :
1. the love inwishlist icon function only for full heart and if you click again cannot change.
2. the my wishlist cannot show the product. and remove icon not function.
3. nothing show in wishlist data base after click on product page.
I already follow your tutorial. i hope someone can help me. this is really important for our web. without this we cannot launch this web. wishlist last system that we need.
and i try to replicate copy paste into new web . but i doesnt work. Here is the code i use.
My Wishlist
Here is the code of My Wishlist
// For full API documentation, including code examples, visit http://wix.to/94BuAAs //-------------Imports-------------// // Import the wix-data module for working with queries. import wixData from 'wix-data'; // Import the wix-users module for working with users. import wixUsers from 'wix-users'; // Import the wix-location module for navigating to pages. import wixLocation from 'wix-location'; //-------------Page Setup-------------// $w.onReady(async function () { // Get the current user. let user = wixUsers.currentUser; // If the current user is logged in: if(user.loggedIn) // Load the user's wishlist using the loadWishlist() function. return loadWishlist(); // If the current user is not logged in: // Collapse the wishlist. $w('#wishlist').collapse(); // Expand the empty whishlist. $w('#emptyWishlist').expand(); }); // Load and display the current user's wishlist. async function loadWishlist(){ // Get the current user. let user = wixUsers.currentUser; // Query the "Wishlist" collection for all wishlist items belonging to the current user. let wishlistResult = await wixData.query("Wishlist") .eq("userId", user.id) .include('product') .find() // If any wishlist items were found: if (wishlistResult.length > 0) { // Expand the wishlist. $w("#wishlist").expand(); // Collapse the empty wishlist. $w("#emptyWishlist").collapse(); // Set the wishlist repeater's data. $w("#wishlist").data = wishlistResult.items; // Set the action that occurs when the wishlist repeater items are loaded to the myItemReady() function. $w('#wishlist').onItemReady(myItemReady); } // If no wishlist items were found: else { // Collapse the wishlist. $w("#wishlist").collapse(); // Expand the empty wishlist. $w("#emptyWishlist").expand(); } } // Set up the wishlist repeater items when the repeater's data is loaded. function myItemReady($w, wishlistItem){ // Get the wishlist product. let product = wishlistItem.product; // Get the product information from the product database wixData.get("Stores/Products", product) .then((productRecord) => { // Set the repeater's elements using the item data. $w('#productImage').src = productRecord.mainMedia; $w('#name').text = productRecord.name; $w('#price').text = productRecord.formattedPrice; }); // Set the action that occurs when the product image is clicked. $w('#productImage').onClick(() => { // Navigate to the wishlist item's product page. wixLocation.to(product.productPageUrl); }); // Set the action that occurs when the remove item image is clicked to the removeItem() function. $w('#removeItem').onClick(removeItem(wishlistItem._id)); } // Remove an item from the user's wishlist. function removeItem(id) { return async function() { // Remove the item with the specified ID from the "Wishlist" collection. await wixData.remove('Wishlist', id); // Reload the wishlist to reflect the removed item. loadWishlist(); } }
Here is the code i use in Product Page
// For full API documentation, including code examples, visit http://wix.to/94BuAAs //-------------Imports-------------// // Import the wix-data module for working with queries. import wixData from 'wix-data'; // Import the wix-users module for working with users. import wixUsers from 'wix-users'; // Import the wix-location module for navigating to pages. import wixLocation from 'wix-location'; //-------------Page Setup-------------// $w.onReady(async function () { // Get the current user. let user = wixUsers.currentUser; // If the current user is logged in: if(user.loggedIn) // Load the user's wishlist using the loadWishlist() function. return loadWishlist(); // If the current user is not logged in: // Collapse the wishlist. $w('#wishlist').collapse(); // Expand the empty whishlist. $w('#emptyWishlist').expand(); }); // Load and display the current user's wishlist. async function loadWishlist(){ // Get the current user. let user = wixUsers.currentUser; // Query the "Wishlist" collection for all wishlist items belonging to the current user. let wishlistResult = await wixData.query("Wishlist") .eq("userId", user.id) .include('product') .find() // If any wishlist items were found: if (wishlistResult.length > 0) { // Expand the wishlist. $w("#wishlist").expand(); // Collapse the empty wishlist. $w("#emptyWishlist").collapse(); // Set the wishlist repeater's data. $w("#wishlist").data = wishlistResult.items; // Set the action that occurs when the wishlist repeater items are loaded to the myItemReady() function. $w('#wishlist').onItemReady(myItemReady); } // If no wishlist items were found: else { // Collapse the wishlist. $w("#wishlist").collapse(); // Expand the empty wishlist. $w("#emptyWishlist").expand(); } } // Set up the wishlist repeater items when the repeater's data is loaded. function myItemReady($w, wishlistItem){ // Get the wishlist product. let product = wishlistItem.product; // Get the product information from the product database wixData.get("Stores/Products", product) .then((productRecord) => { // Set the repeater's elements using the item data. $w('#productImage').src = productRecord.mainMedia; $w('#name').text = productRecord.name; $w('#price').text = productRecord.formattedPrice; }); // Set the action that occurs when the product image is clicked. $w('#productImage').onClick(() => { // Navigate to the wishlist item's product page. wixLocation.to(product.productPageUrl); }); // Set the action that occurs when the remove item image is clicked to the removeItem() function. $w('#removeItem').onClick(removeItem(wishlistItem._id)); } // Remove an item from the user's wishlist. function removeItem(id) { return async function() { // Remove the item with the specified ID from the "Wishlist" collection. await wixData.remove('Wishlist', id); // Reload the wishlist to reflect the removed item. loadWishlist(); } }
Here is how it is look like on my collection data base Wishlist. In the product section nothing show.
it doesnt work for me :( anyone can help. in my dummies web in works fine. in real, i copy paste every code and step. but different result. anyone know what is the problem??
@Steve Cropper, i wish there were more members like you, while i am not dealing with an issue like this, i absolutely love the fact you took the time to help and teach people how they can find answers themselves.
Excellent! Can I ask you add a Top Comment to the post to let others know it has been answered? Good luck with the rest of your site.
Delete line 72. The red dot is flagging an error in your code. It is telling you that you have terminated the function already (on line 72) if you remove the } (this ends the function definition). It should do what you want. The function ends on line 79 (where the red dot error is being flagged). You will know if you have deleted the right line because the red dot will go away!
Oh my Jesus. I feel like I'm so close to getting it right..
This is what I did:
And got:
1. I hate those darn parsing errors and don't 100% know how to deal with them
2. The information shows up in my repeater but its not showing the exact data that it's supposed to - the actual image of the product that I have saved to my wishlist, it's name, and price.
The wishlist data is supposed to be what the customer adds to the wishlist from the product pages. Its member manipulated so its different than you adding a gallery that you change the images for and that everyone can see. A wishlist can only be seen by the member who has created that list.
Besides that, yes, I have tried doing that but it defeats the purpose of the wishlist and doesn't function like a wishlist should.
Have you tried using the Connect to Data feature on the repeater Gallery instead of using code to see if that changes the behavior? I have a Pro Gallery that I have connected to the dataset as a category page and lists a bunch of locations that I have stored in a collection. https://www.fishonbassanglers.com/Tournaments/Locations
The Connect to Data on it is configured as shown below