const commerce = new Commerce(process.env.REACT_APP_API_KEY)
const [shopItems,setShopItems] = useState("")
useEffect(()=> {
commerce.products.list().then((product) => {
setShopItems(product)
console.log(shopItems.data)
});
}, [])
function categorize(category) {
let categoryarray = []
shopItems.data.forEach(el=> {
if (el.categories.slug == category) categoryarray.push(el);
})
console.log(categoryarray)
}
whenever I call categorize it says that shopItems has not been defined although I clearly defined it when calling useEffect. Can anyone help me with this? Thanks in Advance.
it says that shopItems itself reverted back to the original state value, which is just “” (cant read .data of undefined), and yes, I totally forgot about filter. Thanks
oh sorry, I meant shopItems.data was undefined. weird thing is, when i console log shopItems.data in useEffect it also returns undefined. But, if I console.log(shopItems) before console.log(shopItems.data) it goes back to normal
How is categorize being called? Are you sure that shopItems is getting populated first?
If you are calling it somewhere in your component “automatically” (as opposed to triggered by a user interaction) then it may be called before that variable is set. One solution would be to put protection, like:
it’s not called automatically, I mapped the categorize function to an onClick event, so I doubt that it’s the case. I have not uploaded this project so no repo yet im afraid
Sorry, but then I’m not sure how to help. There is something wrong with the sequence of events here and I don’t think I can get it without more info. Could you at least post that entire file?
If you want to log out shopItems you can create a useEffect just for logging state. Just put the state you want to log in the dependencies so it gets logged any time it changes.
If shopItems.data is undefined inside your onClick function you might not be getting back the data as expected. I would suggest you just log out everything. Log commerce first to check it, then log product inside the .then() and then check shopItems inside the useEffect log.
it’s working now, but then it never stops logging, which I want to avoid, although it is not my top prioriity (although I can just stop console logging, but idk the implications it has on memory usage and such) . Any other suggestions?
EDIT: nevermind, apparently once i erased console.log(shopItems) from my useEffect, the error comes back again.
This type of logging is really only meant for development, not production. So it doesn’t really matter what effect it might have on performance. Although you would have to have an incredible amount of logging to affect performance and memory usage.
I don’t understand what you mean by this, nor do I know which useEffect you are talking about. I don’t see how removing a log from a useEffect can cause an error, even though you haven’t actually told us what error, “the error” is not very helpful information.
We do not have access to your data so we can’t know what is expected. We can only assume that shopItems.data is an array of objects that should be available as state after you set it inside the async code.
You will likely have to provide us with a live working example on something like CodeSandbox.
im not really sure how to do that in codesandbox (with Commerce.js and all that) but I do have a stackoverflow post (that no one has replied to yet unfortunately), which shows the data fetched.
and yes shopItems.data is indeed an array of objects.
I too am confused by this, since it doesnt really make any sense to me. Right after I remove the console.log(shopItems) it says:
TypeError: Cannot read properties of undefined (reading ‘forEach’)
actually this was the case the entire time. I waited for 2 seconds and everything went back to normal. That was really stupid and impatient of me. Thanks!
I’m still not sure I understand. What I infer is that the Promise in useState was taking longer to finish than you were expecting so you were calling categorize before the data was ready?
That should be easy to figure out with some carefully placed log statements. In any case, if that is what is happening, I would disable the button until the data is ready, either through a state variable or by checking if the data is valid (again, it should never be a string if the final data is an object.)