Trying to sort through array object using .map - javascript

I've got the following code where I'm trying to loop through the array of objects, but for some reason it's telling me data.map is not a function, even though I know data has content in it.
function Tree({ data }) {
let count = 0;
return (
<>
{data.map(item => {
count += 1;
console.log("Item", item.name);
return (
<div key={count} className="node">
{/* {item.name} */}
</div>
);
})}
</>
);
}
export default Tree;
When I change it over to Object.entries, I get stuff back, but that's not how I've done this in the past so I'm a little confused on the issue here.
function Tree({ data }) {
let count = 0;
return (
<>
{Object.entries(data).map(item => {
count += 1;
console.log("Item", item.name);
return (
<div key={count} className="node">
{/* {item.name} */}
</div>
);
})}
</>
);
}
export default Tree;
The array object is constructed like so:
[
{
id: 0,
name: Brannon,
},
{
id: 1,
name: John,
}
]

Console log data. You will get this message when the data you are trying to map is not an array. When you run Object entries you are turning the object into an array consisting of its keys and values. So this implies that the original data is just a plain object and not an array.
Also just a tip map will auto handle index for you if you pass it as a second parameter instead of manually handling it as you are.
{Object.entries(data).map( (item, count) => {
//count += 1; remove this it will auto increment
console.log("Item", item.name);
return (
<div key={count} className="node">
{/* {item.name} */}
</div>
);
})}

Try,and write console.log output of data if it not help
function Tree({ data }) {
console.log("data", JSON.stringify(data));
return (
<>
{ data && data.map((item, index) => {
console.log("Item", item.name);
return (
<div key={index} className="node">
{/* {item.name} */}
</div>
);
})}
</>
);
}
export default Tree;

Related

React nested rendering

I have an object containing several arrays like:
const Items = {
Deserts: [{name:cookies}, {name:chocolate}],
Fruits: [{name:apple}, {name:orange}]
...
}
I want to render it as:
<title>Deserts</title>
Cookies
Chocolate
<title>Fruits</title>
Apple
Orange
So first I render the type:
return <Grid>
{Object.keys(Items).map(type => {
return <Box key={type}>
{type} // <== this would be the title, Fruits or whatever
{this.createCard(Items[type])}
</Box>
})}
</Grid>
Then I want to add the content of each type:
createCard = (items) => {
return <Box>
{items.forEach(item => {
return <div>{item.name}</div>
})}
</Box>
}
Content is not returned, it works fine if instead of a forEach loop I just add some predefined content.
The forEach method only iterates over all items but does not return anything. Instead, what you want to use is a map.
Also, make sure you wrap your return value when it extends more than one line:
createCard = (items) => {
return (<Box>
{items.map(item => {
return <div>{item.name}</div>
})}
</Box>);
}
If you don't do that it works as if a semicolon was introduced after the first line. So, in reality, your current code is equivalent to:
createCard = (items) => {
return <Box>;
// The code below will never be executed!
{items.forEach(item => {
return <div>{item.name}</div>
})}
</Box>
}
When returning an element you need to wrap it in parentheses, ( ) and I generally use map instead of forEach.
const createCard = items => {
return (
<Box>
{items.map(item => {
return ( <div>{item.name}</div> )
})}
</Box>
)
}
I believe you can also nix the curly braces if the function doesn't need any logic.
const createCard = items => (
<Box>
{items.map(item => {
return ( <div>{item.name}</div> )
})}
</Box>
)
-- Edit --
Now that I'm reading back over your question a much cleaner way to approach this would be to declare the component function outside of your class like
class Grid extends react.Component {
render(){
return (
<Box>
<CreateCard props={ item }/>
</Box
)
}
}
const CreateCard = props => (
<Box>
{props.items.map(item => {
return ( <div>{item.name}</div> )
})}
</Box>
)

How can i achieve 100% reusability of that react-bootstrap component?

I am trying to create a reusable carousel using react-bootstrap, i could create that one"
const ReusableCarousel = (props) => {
return (
<Carousel className="mt-4 border">
{props.items.map((item, index) => {
return (
<Carousel.Item key={index}>
<Row>
{props.children}
</Row>
</Carousel.Item>
);
})}
</Carousel>
);
}
Now as you see it is reusable till the point of the carousel item, props.children may represent multiple elements per one slide or single element per slide, but i can not achieve that according to my logic
in the parent:
<ReusableCarousel items={categories}> //categories is an array of arrays of objects
{
//item prop should be passed here to carouselItemCategories component
//but i couldn't find a way to achieve that
<CarouselItemCategories key={i} />
}
</ReusableCarousel>
carouselItemCategories Component:
const CarouselItemCategories = (props) => {
//still in my dreams
const { item } = props;
return (
<>
{
item.map((c, index) => {
return (
<Col key={index}>
//a category card here
</Col>
);
})
}
</>
);
}
Now i know what makes it work, it is about passing item prop(which represent an array of objects represents fraction of my categories) but i could not find any way to achieve that
you can imagine categories like that:
const categories = [
[
{
title: 'Laptops',
background: 'red'
},
{
title: 'Tablets',
background: 'blue';
}
],
[
{
title: 'Mouses',
background: 'yellow'
},
{
title: 'Printers',
background: 'orange';
}
]
]
If I understand you correctly, you want to use each of the items from your ReusableCarousel to generate a new CarouselItemCategories with the individual item passed in as a prop?
If so, you may want to take a look at the cloneElement function. Effectively, inside your mapping of the items prop, you would create a clone of your child element, and attach the individual item as a prop to that clone. Something like this:
const ReusableCarousel = (props) => {
return (
<Carousel className="mt-4 border">
{props.items.map((item, index) => {
return (
<Carousel.Item key={index}>
<Row>
{React.cloneElement(props.children, { item })}
</Row>
</Carousel.Item>
);
})}
</Carousel>
);
}
I just found another solution by using react context, i created a CarouselContext module :
import React from 'react';
const CarouselContext = React.createContext([]);
export const CarouselProvider = CarouselContext.Provider;
export default CarouselContext
and then in the ReusableCarousel component:
import { CarouselProvider } from './carouselContext'
const ReusableCarousel = (props) => {
return (
<Carousel >
{props.items.map((item, index) => {
return (
<Carousel.Item key={index} >
<Row >
{
<CarouselProvider value={item}>
{props.children}
</CarouselProvider>
}
</Row>
</Carousel.Item>
);
})}
</Carousel>
);
}
and then using the context to get item global variable
const CarouselItemCategories = () => {
const item = useContext(CarouselContext);
return (
<>
{
item.map((c, index) => {
return (
<Col>
//category card here
</Col>
);
})
}
</>
);
}

How to properly print values from a nested loop in a react render() method?

As you can see in my code example below which is part of a render() block in a react component, I am trying to render the value of the variable "folder" in the outer loop. Unfortunately, the code section
<div>{folder}</div>
seems to be ignored. Can anyone help me in finding the right syntax that outputs the current folder value from the outer loop?
{
folders.map((folder,_index1) => {
<div>{folder}</div>
return (
items.map((item, index) => {
return (
<div>
{(folder === item.folder) ?
<Draggable
key={item.id}
draggableId={item.id}
index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{ ...provided.draggableProps }
{ ...provided.dragHandleProps }
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}>
<div>
{item.content}
</div>
</div>
)}
</Draggable>
: null
}
</div>
)})
)})
}
Following Zydnar's comment above:
This is what it should look like:
{
folders.map((folder,_index1) => {
return (
<> // or <React.Fragment> with the corresponding closing tag
<div>{folder}</div> // this has to be part of what is returned
items.map((item, index) => {
return (
<div>
{(folder === item.folder) ?
...
</>
)})
)})
}

How to .map() a JSON response from a get request and use the index that is inside the given index to determine table rows

So this is what the JSON response looks like,
and what my project is displaying
and my render looks like this:
render() {
const { materials } = this.state;
let returndata = _.isEmpty(materials) ? [] : materials
console.log('look', returndata)
return (
<div className="ui container">
<br />
<br />
<Table fixed>
<Table.Header>
<Table.Row>
<Table.HeaderCell>UUID</Table.HeaderCell>
<Table.HeaderCell>Title</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{returndata.map((item, i) => {
return (
<Table.Row key = {i}>
<Table.Cell>{item.uuid}</Table.Cell>
<Table.Cell>{item.title}</Table.Cell>
<Table.Cell>{item.description}</Table.Cell>
</Table.Row>
)
})}
</Table.Body>
</Table>
</div>
);
}
what should I do to be able to show the data(16 items) from [0] and 1 without hardcoding them, because someday I might have more arrays and not just 0 and 1.
thanks!
try this?
const aggregated = data.reduce( (agg, list) => {
return agg.concat(list.data)
}, [])
return ({aggregated.map((item, i) => Table.Row....})
Try:
<Table.Body>
{
returndata.map((item, i) => {
return (
<Table.Row key = {i}>
{
item.map(innerdata => {
return(
<Table.Cell>{innerdata.uuid}</Table.Cell>
<Table.Cell>{innerdata.title}</Table.Cell>
<Table.Cell>{innerdata.description}</Table.Cell>
)}
)}
</Table.Row>
)}
)}
</Table.Body>
The innerdata is part of an array inside the array.

How to add radio button in react native?

I want to add radio button in react native, which is pretty simple and I've done it. But the thing is I want to loop through the radio button upon the contents fetching from a server.So the list depends on the number of items fetching which is changing.The data I'm fetching is as follows
json data
{
"data": [{
"content": "question",
"selection": [
"(a).option1",
"(b).option2 ",
"(c).option3 ",
"(d).option4 "
],
"correct": "4",
}]
}
Well, I'm displaying content inside a CardSection component.I want to loop through the selection array with corresponding radio buttons.I'm using map method for rendering the data. So for selection what should I use?A for loop is okay for that?But I don't know how to do it please do help.Following is the react part.
updated
const formatArray = (arr) => {
let newArr = []
arr.map((item, index) => newArr.push({'label': index, value: item}))
return newArr
}
class QASection extends Component{
render() {
_setActive = (active) => this.setState({this.setState({selected:value})})
return(
{this.state.details.map(a =>
<Card>
<CardSection>
<Text>{a.content}</Text>
</CardSection>
<CardSection>
<RadioForm
radio_props={radio_props}
initial={0}
itemShowKey="label"
itemRealKey="value"
dataSource={formatArray(data)}
onPress={onPress}
/>
<CardSection data={data} key={index} onPress={this._setActive} />
</Card>
)}
);
}
}
By rendering selection[0] it will give me the first value in selection array. But how do I loop through this with radio buttons for each item in an array?
You can loop in the following way
I assume that you are using react-native-radio-form
const formatArray = (arr) => {
let newArr = []
arr.map((item, index) => newArr.push({'label': index, value: item}))
return newArr
}
const YourCardComponent = ({data, onPress}) => {
return (
<Card>
<CardSection>
<Text>{data.content}</Text>
</CardSection>
<CardSection>
<RadioForm
radio_props={radio_props}
itemShowKey="label"
itemRealKey="value"
dataSource={formatArray(data.selection)}
onPress={onPress}
// ... other props as required
/>
</CardSection>
</Card>
)
}
// Inside the class
_setActive = (active) => this.setState({selected:value})
render () {
const {details} = this.state
return (
<View>
{details.map((data, index) => (
<YourCardComponent data={data} key={index} onPress={this._setActive} />
))}
</View>
)
}

Categories

Resources