top of page

Forum Posts

Brian
Jun 09, 2021
In Coding with Velo
When I view my page in preview, it works fine; when I load my page, it works fine; but when I use wixLocation.to(path) to move from one dynamic page to another, certain elements in repeaters don't load properly. Things like setting the element.style property and .show()/.hide() don't seem to work. When logging within the onItemReady() of the repeater, it shows the correct values being logged, but the code seems to interact with the elements BEFORE the page is done switching to the new dynamic page but then load the default values of said elements. wixLocation.to(baseUrl+path) works, but that seems to reload the page entirely as if you were going to a different site rather than navigating within the same site, if that makes any sense. For example: the color options on the right are suppose to load with a red outline indicating the current color, when I click to another product, you can see the white is deselected and the yellow circle shrinks (which is part of the script so that the red outline and the actual color has some empty space in between), however then it just goes back to the default color of the circle element (which is the same red as the outline) // the page's onReady calls a function that calls loadColorOptions() async function loadColorOptions(color, product) { let skuP1 = product['skuP1'] let currentColor = product[color][0]['value'] $w('#' + color + 'Text').text = 'Color: ' + currentColor $w('#' + color + 'Repeater').onItemReady(($r, option) => { colorOnReady($r, option, color, product) }) await wixData.query('MyStore') .limit(100) .eq('skuP1', skuP1) .distinct(color) .then((result) => { $w('#' + color + 'Repeater').data = result.items.sort(function (a, b) { return sortColors(a, b) }) $w('#' + color + 'Repeater').show() }) } function colorOnReady($r, option, color, product) { let currentColorHex = product[color][0]['hex'] let currentColor = product[color][0]['value'] $r('#' + color + 'OptionCircle').style.backgroundColor = option.hex if (option.hex === currentColorHex) { $r('#' + color + 'OptionCircle').style.borderWidth = '4px' $r('#' + color + 'OptionCircle').style.borderColor = '#FFFFFF' $r('#' + color + 'OptionCircleOutline').show() } else { $r('#' + color + 'OptionCircle').style.borderWidth = '1px' $r('#' + color + 'OptionCircle').style.borderColor = '#000000' $r('#' + color + 'OptionCircleOutline').hide() } } I have tried calling the functions using onChange(), after the wixLocation.to(), placing it in the dataset.onReady, but none of those work. Is this a bug or what am I missing here?
wixLocation.to(path) doesn't load dynamic pages properly content media
0
3
84
Brian
May 27, 2021
In Coding with Velo
Quick Version of the Question Consider the following where 'a' and 'b' are the values for a field called 'c' in a dataset. How can I get the targetOutput? a = [1, 2, 3] b = [1, 2] distinct('c') // targetOutput = [1, 2, 3], [1, 2] // actualOutput = [1, 2, 3] More details: I have a field of product colors. Some are just one solid color, some are a combination of colors. The current way distinct() seem to work is that it treats each index of an array as it's own value which is actually good for a page with all the products and to filter products that have a certain color, but for product page where you want to separate variants by the color combinations, you just get [red, blue] instead of something like [red, blue, [red, blue]]. Is the only way to have something like primary color and secondary color fields?
0
0
21
Brian
Apr 20, 2021
In Coding with Velo
While trying to debug, I have simplified and hardcoded it to go to page 2 of a dataset. $w('#productsList').onReady(function () { $w('#productsRepeater').onItemReady(productItemReady) // updateFilterSelectedN() // reloadProductsBasedOnFilter() // sortProducts() $w('#productsList').loadPage(2) }) When I load the page, I get this error in the developer console and it fails to load: supplementaryErrorHandlers.js:22 Wix code SDK error: The currentPage parameter that is passed to the currentPage method cannot be set to the value 1.75. It must be of type integer,null. As you can see 2 is being passed into the loadPage() but developer console shows it receiving 1.75. If I pass in a 3 it spits an error saying it got 2.5. If I set up a test button and have it perform the loadPage(pgNumber) it performs fine for some reason, but when I have it within the onReady function it doesn't work at all.
0
10
61
Brian
Feb 27, 2021
In Coding with Velo
From what I understand, you can only use .add() and .remove() to edit queryParam, however this is far from optimal. Consider the following: a user is viewing /shop?category=["ring"]&page=2 changes the filter to have only diamond rings and you want the queryParam to become something like /shop?category=["ring"]&material=["diamond"]. You have to add '{material:diamond}' to the queryParam and then remove 'page'. However, when you use an .add() and .remove(), each step is recorded into the browsing history automatically. There doesn't seem to be anyway to prevent the browser from storing it into the history, so the user's history becomes something like this: 1. /shop?category=["ring"]&page=2 2. /shop?category=["ring"]&page=2&material=["diamond"] 3. /shop?category=["ring"]&material=["diamond"] This isn't too big of an issue while going from 1 to 3, as it just skips 2 without the user even noticing, but when the user wants to back, the browser brings them to the queryParam from 2 which the user never actually went to and may not even be a valid queryParam necessitating an extra back navigation despite in the users POV, they should only need to click it once as they never even see 2. A workaround is to not remove page and instead set page=1 so that you get and add the material queryParam as usual: 1. /shop?category=["ring"]&page=2 2. /shop?category=["ring"]&page=1&material=["diamond"] But that just looks a bit sloppy and while most people probably don't really care about the URL, from a "developer's" point of view, it just looks unpolished, and now you're stuck with an arguably unnecessary queryParam This issue also extends to the inability to keep queryParams in a consistent order ie: category, material, color. With the current limitations, it seems the order of the queryParam is dictated by the order in which the customer chooses the filter. So if someone clicks material first and then category it becomes: 1. /shop?material=["diamond"] 2. /shop?material=["diamond"]&category=["ring"] Rather than the order I want which is: /shop?category=["ring"]&material=["diamond"] Again, while these issues are minor, the simple inclusion of a queryParam.replace() or something similar that would allow the complete replacement of queryParam would solve these minor issues easily and make the website much more polished in both the way it looks and the way it runs.
1
0
21
Brian
Feb 10, 2021
In Coding with Velo
Purpose: I've noticed that if I scroll down to the 50th or whatever product in my store page and click on said product, when I click back it loads back to the top. I've written a script that is suppose to load the repeater until it reaches the index that is added to the queryParam before the user went to that product page and then scroll down to that row. Background/the Code: I have the following function that uses $w('#element').scrollTo() async function scrollTo(index){ if(!index){ let queryParam = wixLocation.query     index = queryParam['i'] if (!index) { return     }   } // PART ONE let productData = $w('#productsRepeater').data if (index >= productData.length) { await loadMoreProducts()     scrollTo(index)   } // PART TWO else{ let targetID = productData[index]._id     $w('#productsRepeater').forItems([targetID], ($item)=>{      $item('#productContainer').scrollTo()     })   } } the loadMoreProducts() function is simply using .loadMore() along with expanding/collapsing various things to show that its loading more products export async function loadMoreProducts(event) { if($w('#productsList').hasNext()){     $w('#loadingMoreAnimation').expand() await $w('#productsList').loadMore()     .then(() => {       $w('#loadingMoreAnimation').collapse()       $w('#stripLoadMore').expand()     })   } else{     $w('#stripLoadMore').collapse()   } } For the purpose of testing, I've set the pageSize to 4 otherwise all the products will be loaded at once, and I get a better idea of how fast it runs. I've also created a button that runs scrollTo(35) to eliminate the need to click into the product and then back out as well as eliminate any question about it being related to the queryParam. The test site: https://briapril30.wixsite.com/website-3/shop Problem: When I click on the button the first time (when it has not loaded the target index yet), it loads more products properly, but gives the error "Uncaught (in promise) TypeError: Cannot read property 'getBoundingClientRect' of null" in the developer console. This shows that everything in PART ONE does as expected and something seems to be wrong with PART TWO. However when I click the button a second time (when the target product has been loaded), it scrolls properly to the target index, so clearly PART TWO on its own works as well, despite the documentation saying it doesn't work on elements in repeaters. For whatever reason when running the code the when the target index has not loaded yet causes PART TWO to not work and results in that type error. Things I've Already Tested: I thought it was due to the loadMoreProduct function finishing without the ('#productContainer') element finish rendering, but it still gave me that error when I add a if(('#productContainer').render) test. I tried separating the two parts into two different scripts and then have a partOne().then(partTwo()) type of thing but that didn't work either. I commented out $item('#productContainer').scrollTo() and didnt get that error, so the error is definitely involving that line of code. Any help or suggestions would be appreciated
0
0
428
Brian
Nov 19, 2020
In Coding with Velo
I call the following function at the end of my filter function to change the queryParam function updateQueryParam(filterObj){ let queryParam = filterObj for (let key in queryParam) { if (!queryParam[key].length === 0 || Object.keys(queryParam[key]).length === 0){ delete queryParam[key]     } else if (key === 'collection'){       queryParam[key] = JSON.stringify(queryParam[key])     }   } wixLocation.queryParams.remove(Object.keys(wixLocation.query))  console.log('original wixLocation.query') console.log(wixLocation.query)  console.log('queryParam') console.log(queryParam)  wixLocation.queryParams.add(queryParam)  console.log('new wixLocation.query')  console.log(wixLocation.query) } I select "ring" from my filter and the query string is correctly changes to "?category=ring" and I get the following log (edited for readability) original wixLocation.query : {} queryParam : {"category":["ring"]} new wixLocation.query: {"category":["ring"]} However when I unselect the "ring" the URL query string remains as "?category=ring" despite getting the following log: original wixLocation.query : {"category":["ring"]} queryParam : {} new wixLocation.query: {} And when I go to select "ring" again, I get the following log: original wixLocation.query : {"category":["ring"]} queryParam : {"category":["ring"]} new wixLocation.query: {"category":["ring"]} From the logs as well as observing the URL, remove does what it should in the code as the new wixLocation.query === queryParam, but it doesn't actually change the URL nor do the changes get saved. This issue gets compounded when I select multiple categories and it becomes something like "?category=ring&category=earring&category=bracelet" with nothing getting removed. Am I implementing this wrong or is this yet another bug? I have read that remove is bugged when trying to run it multiple times within a function. But that was almost a year ago.
0
5
81
Brian
Nov 12, 2020
In Coding with Velo
I have a product filter set up in a lightbox. I used session.setItem to save the selected and use session.getItem to retrieve it. I use session because I want the selection to be preserved when moving between the product page and product gallery so that users don't have to reselect everything and it does work on desktop version where I don't use a lightbox. However I have the following psuedocode going on : starting on productGallery on desktop version select red then switch to mobile version session.getItem('filterObj') returns ['red'] open the filter lightbox, session.getItem('filterObj') returns [] user selects "blue", add "blue" to filterObj and session.setItem('filterObj', filterObj) session.getItem('filterObj') returns ['blue'] close lightbox to return to productGallery and session.getItem('filterObj') returns ['red'] Essentially it seems lightbox has its own 'session' independent of the site's 'session'. Is this yet another bug of Corvid? It's does not seem to be documented anywhere that lightbox have their own 'session' nor should they in my opinion. I know I can pass data from lightbox through coding, but it would be redundant since it would mean that I would have to pass the data and then run session.setItem again even though it already did when the user chooses what filters to add.
0
3
56
Brian
Oct 20, 2020
In Coding with Velo
The documentation says the following but doesn't make any mention of options that has spaces For example, if you have a product option called "Size," you can use productOptions.size.value in your code (note that the case of the name doesn't matter). If you have a product option called "Color," you use productOptions.color.value. You can also use any custom options you may have defined. The name you use is the name of the option in your store. I have a productOption called "Base Color" and I have tried: let result = await wixData.query('Stores/Products') .hasSome('productOptions.base color.value', '#f2f2f2') .hasSome('productOptions["Base Color"].value', '#f2f2f2') .hasSome('productOptions.baseColor.value', '#f2f2f2') .hasSome('productOptions.base color.description', 'white') .hasSome('productOptions["Base Color"].description', 'white') .hasSome('productOptions.baseColor.description', 'white') None of these work.
0
2
56
Brian
Oct 20, 2020
In Coding with Velo
I wanted to clean up my code and move some of the helper functions into another file. The code worked fine until I moved the following two functions into a backend file. If I copy the functions back into the file it will tell me that those two functions are already declared indicating that it is imported correctly and I've tested (via console.log) that both functions run properly but the .sort() seems to ignore the results and does nothing with it. If I copy the functions back and delete the import line (basically revert it to the way it originally was) it works fine. export function sortColors(a, b) { let aHSL = hexToHSL(a.hex) let bHSL = hexToHSL(b.hex) if (aHSL[1] < bHSL[1]) { return -1; } if (aHSL[1] > bHSL[1]) { return 1; } if (aHSL[0] < bHSL[0]) { return -1; } if (aHSL[0] > bHSL[0]) { return 1; } if (aHSL[2] < bHSL[2]) { return -1; } if (aHSL[2] > bHSL[2]) { return 1; } return 0; } export function hexToHSL(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); var r = parseInt(result[1], 16); var g = parseInt(result[2], 16); var b = parseInt(result[3], 16); r /= 255, g /= 255, b /= 255; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, l = (max + min) / 2; if (max === min) { h = s = 0; // achromatic } else { var d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } s = s * 100; s = Math.round(s); l = l * 100; l = Math.round(l); h = Math.round(360 * h); return [h, s, l] } The sort is imported and called via the following code: import {hexToHSL, sortColors} from 'backend/colorOptionsFunctions' //BUNCH OF OTHER CODE setColorData.sort(function(a,b){ return sortColors(a, b) }) I don't think you need to do anything special when calling the function so what is wrong? is this something on Wix's end?
0
3
80
Brian
Oct 15, 2020
In Coding with Velo
Background I have the following two codes. One that fetches a query without a limit and then uses native js slice to load slices of the data at a time. One that fetches a query with a limit and then uses Corvid code to get the next slice of data. Using js slice: async function loadProducts() { let productListAll = await wixData.query('Stores/Products') // .limit(productsToLoad) .find(); productListAll = productListAll.items console.log(productListAll) if (productListAll.length > 0){ if(productsLoaded === 0){ let productList = productListAll.slice(productsLoaded, productsLoaded + productsToLoad) productsLoaded += productsToLoad showProducts(productList) } while(productsLoaded <= productListAll.length){ let productList = productListAll.slice(productsLoaded, productsLoaded + productsToLoad) productsLoaded += productsToLoad showMoreProducts(productList) } } } Using Corvid hasNext() and next(): async function loadProductsViaNext() { let productList = await wixData.query('Stores/Products') .limit(productsToLoad) .find(); if (productList.items.length > 0){ if(productsLoaded === 0){ productsLoaded += productsToLoad showProducts(productList.items) } while(productList.hasNext()){ productList = await productList.next() productsLoaded += productsToLoad showMoreProducts(productList.items) } } } Issues (performance and reliability) Right now I only have about 40 test products and the native JS code works fine and even seems faster. When I timed it using the date method (Corvid can't use performance.now() for some reason) the JS method returned an average time of about 1500 milliseconds while the Corvid method returned an average time of 5000+ milliseconds. Using Corvid's hasNext() and next() also gives errors like: Wix code SDK Warning: The data that was passed to data contained at least two items with the same ID: 8c90d74c-68aa-44bc-8140-0cb1de0ed30b. Only the first item was accepted. However, it is inconsistent in that it's not always the same ID in that error. It also causes items to not load properly as it loads the wrong ID. In theory productList = await productList.next() productList = productList.items should return the same thing as let productList = productListAll.slice(productsLoaded, productsLoaded + productsToLoad) but .next() returns inconsistently incorrect values. Sometimes it's only 3 Id errors, sometimes it's over a dozen. The only consistency I could find is that it seems to happen to items in the middle no matter how the items are sorted. Questions Why is this happening? How do I fix this? Why is Corvid code involving query so slow? Is it even worth figuring out how to fix this issue or should I just set it up to use as much native JS as possible to improve performance?
0
2
135

Brian

More actions
bottom of page