I have this Object in my state : console.log(state)
I created a component to render a card for each entry in this object (which has under object)
I have tried everything, but I always get an error. Here is my last attempt :
import { useState } from "react"
export default function Categories(props: any) {
const [listOfCategories, setListOfCategories] = useState(props.datas.categories)
console.log(listOfCategories)
return (
<>
{listOfCategories.map(category => {
return (
<div key={category} className="relative flex flex-wrap h-96 my-20">
<div className="absolute right-0 top-0 h-full">
<img className="rounded-lg max-w-full h-96" src="https://double-you-design.fr/wp-content/uploads/2016/04/dummy-post-horisontal.jpg" alt="" />
</div>
<div className="absolute -bottom-10 bg-white rounded-lg shadow-lg w-7/12 h-48 p-8">
<p key={category}>{category}</p>
</div>
</div>
)
})
}
</>
)
}
the error is : listOfCategories.map is not a function.
My question is : What is the simplest method to do this ? Do you have a recommandation, or an example ?
I am working with TypeScript.
Thank you very much !
CodePudding user response:
You can't use .map
on an object because it is a method of Array.
You could do it with Object.keys like so:
import { useState } from "react"
export default function Categories(props: any) {
const [listOfCategories, setListOfCategories] = useState(props.datas.categories)
console.log(listOfCategories)
return (
<>
{Object.keys(listOfCategories).map((key, ind) => {
return (
<div key={ind} className="relative flex flex-wrap h-96 my-20">
<div className="absolute right-0 top-0 h-full">
<img className="rounded-lg max-w-full h-96" src="https://double-you-design.fr/wp-content/uploads/2016/04/dummy-post-horisontal.jpg" alt="" />
</div>
<div className="absolute -bottom-10 bg-white rounded-lg shadow-lg w-7/12 h-48 p-8">
<p key={ind}>{listOfCategories[key].category}</p>
</div>
</div>
)
})
}
</>
)
}
Here is a simple runnable example to illustrate:
var obby = { a: { category: 'Estimation' }, b: { category: 'Prospection' } }
const categories = Object.keys(obby).map(key => obby[key].category)
console.log(categories)
Another option would be to change your data structure so that you have an array of objects instead of an object of objects - if you have control over that data structure. If not, you could first convert the object to an array.
const obby = { estimate: { category: 'Estimation' }, prospecting: { category: 'Prospection' } }
const arr = Object.values(obby)
const categories = arr.map(val => val.category)
console.log(categories)
Above method in your code:
import { useState } from "react"
export default function Categories(props: any) {
const [listOfCategories, setListOfCategories] = useState(props.datas.categories)
const listOfCategoriesArray = Object.values(listOfCategories)
return (
<>
{listOfCategoriesArray.map((item, ind) => {
return (
<div key={ind} className="relative flex flex-wrap h-96 my-20">
<div className="absolute right-0 top-0 h-full">
<img className="rounded-lg max-w-full h-96" src="https://double-you-design.fr/wp-content/uploads/2016/04/dummy-post-horisontal.jpg" alt="" />
</div>
<div className="absolute -bottom-10 bg-white rounded-lg shadow-lg w-7/12 h-48 p-8">
<p key={ind}>{item.category}</p>
</div>
</div>
)
})
}
</>
)
}