Reputation: 1
I'm trying to loop over an Object that I pass in from the Parent component but its properties return undefined.
I understand the first thing to check would be that the Object is actually not empty, but when I print it in the same useEffect below, it contains all of the data and information that I need. It's only when I loop through it and try to access the individual keys or properties that it is undefined
const [selectedCategory, setSelectedCategory] = useState < string[] > ([]);
useEffect(() => {
console.log(salesTaxData) // This returns the correct existing data
if (salesTaxData !== undefined) {
Object.keys(salesTaxData).map(item => {
if (salesTaxData[item].internalCode !== undefined)
console.log(salesTaxData[item]
.internalCode) // This keeps returning undefined even when the first console log above clearly indicates it does have a value
})
}
}, [salesTaxData]);
EDIT: Extra information:
console.log of the problem This image shows how the original object looks. It shows that both gstHst and pst keys are populated, but when I try to loop over them, they're empty. I also tried the suggestions in the replies below doing it with the for (const x in x) way and the JSON method to console log, but neither method fixed me issue.
Not sure what I'm doing wrong?
Thank you!
Upvotes: 0
Views: 832
Reputation: 9411
console.log
in asynchronous codeWhat is displayed in the console may not be the value at the time of that console.log
was executed, but rather the value at the time you are viewing it. This is a peculiar behaviour of browsers. I think it is intended to be helpful, but I personally find it annoying.
You would be better to reword your console.log as follows:
const [selectedCategory, setSelectedCategory] = useState < string[] > ([]);
useEffect(() => {
console.log("salesTaxData:",JSON.stringify(salesTaxData, null, 2))
if (salesTaxData !== undefined) {
Object.keys(salesTaxData).map(item => {
if (salesTaxData[item].internalCode !== undefined)
console.log("salesTaxData[item].internalCode:",JSON.stringify(salesTaxData[item]
.internalCode,null,2)
})
}
}, [salesTaxData]);
JSON.stringify
to force conversion into a string immediatelyBy doing this, even if the value of salesTaxData
changes later, what is displayed on screen will not change, because it has already been stringified.
The ,null,2
just adds some tidy formatting to the output.
This means it is
(a) searchable
(b) copiable
(c) more quickly viewable
And therefore more likely to get your question answered.
.forEach
rather than .map
.map
is generally used when you are processing an array to make another array, with each element in the first array being mapped to a new element in the second array. e.g.
const doubled = values.map(x=>2*x)
When we see the .map
function we are usually expecting what is inside to it to have no side effects, but rather simply return a new value.
If we are in fact intending to have side effects, we usually signal this to future readers, by using the .forEach
function:
values.forEach(x=>{console.log(x, " times two is ", x*2})
What I am saying is that your line:
Object.keys(salesTaxData).map(item => {
would be easier for future programmers to understand if written:
Object.keys(salesTaxData).forEach(item => {
Upvotes: 1