I am working on a CMS system with nested sub menus that are different depending on user / customization ,etc.
Trying to solve this problem I am placing a map function inside of a react component. As per documentation this approach works with only one nested map fucntion, but apparently not a second one, which is what I need to render sub menus, any ideas?
render() {
return (
<div className="ui dropdown item">
{this.state.text}
<i className="dropdown icon"></i>
<div className="menu">
{multipleOptions.split(',').map(function(option, i){
option.split('#').map(function(subOption, i){
return <a className="item" key={i + "random"}>{subOption}</a>;
})
})}
</div>
</div>
)
}
You need to add return inside first .map
{multipleOptions.split(',').map(function(option, i) {
return option.split('#').map(function(subOption, i) {
return <a className="item" key={i + "random"}>{ subOption }</a>;
})
})}
#AlexanderT.'s answer is correct. It reads a little nicer if you use arraow functions too
{multipleOptions.split(',').map((option, i)=>
option.split('#').map((subOption, i)=>
<a className="item" key={i + "random"}>{subOption}</a>))}
Related
I am trying to implement a search bar and I am going to attach the code for it below. The issue is that when the page reloads and the search bar is empty, no products end up getting render but as soon I start typing something in the search bar, the items start to render as per the search key.
Can anyone assist me with this please?
.filter((val) => {
if (props.searchTerm == "") {
return val;
} else if (
val.additionalInfo.toLowerCase().includes(props.searchTerm)
) {
return val;
}
})
.map((post) => {
return (
<div className="product-metainfo col-2 mb-4">
<img src={post.images[0].src}></img>
<h3 className="product-brand">{post.brand}</h3>
<h4 className="product-product">{post.additionalInfo}</h4>
<div className="product-price">
<span>
<span className="discounted-price">Rs. {post.price} </span>
<span className="product-strike"> Rs. {post.mrp}</span>
</span>
<span className="product-discountPercentage">
({Math.floor((100 * post.discount) / post.mrp)}% off)
</span>
</div>
</div>
);
})}
Did you set the default state for searchTerm as undefined or null? In this case you need to set the default state for searchTerm as empty string to make it work.
I have following code which doesnt show any list as expected.
I am confused why its not working , whats missing .
return (
<div>
List
<ul>
{events.map((event,index)=>{
<li key={index}>Name:{event.name}</li>
})
}
</ul>
</div>
);
Above code is a return block of function component I tried replacing the with many other tags but it just doesnt return anything expect the text outside the map function.
Please help.
You have a typo - you're using { } braces there, in which case you'd need a return too. Failing to have a return in a curly-braced function equals an implicit return undefined;.
return (
<div>
List
<ul>
{events.map((event, index) => {
return <li key={index}>Name:{event.name}</li>;
})}
</ul>
</div>
);
Or, more simply, use regular parentheses to make the return implicit (see Concise body here):
return (
<div>
List
<ul>
{events.map((event, index) => (
<li key={index}>Name:{event.name}</li>
))}
</ul>
</div>
);
I would like to use a map to display the ith value and the i+1th value inside a javascript map to display a set of two cards inside a carousel.
The following is the code I am using, which I would like to modify to get the desired result:
{testimonialContent.map((testimonial, i) => {
return (
<Carousel.Item className={classes.carousel_item}>
<div className={classes.root}>
<div className={classes.testimonial_card}>
{testimonial[i]}
</div>
{/* Second card */}
<div className={classes.second_card}>
{testimonial[i+1]}
</div>
</div>
</Carousel.Item>
Any help or suggestion is appreciated. Thanks.
You can use reduce() to combine data.
NOTE: (index % 2 === 0) is where you specify your nth child (eg: 2 in this case)
Later in your render method use destructuring in map().
const sampleData = ['first', 'second', 'third', 'fourth', 'fifth']
class App extends React.Component {
render() {
console.log("rendered");
const edited = [].concat(sampleData).reduce((unique, value, index) => {
if (index % 2 === 0) {
return [...unique, [value]];
}
unique[unique.length - 1].push(value);
return unique;
}, [])
return (
<div>
{edited.map(([item1, item2]) =>
<div className='block'>
{item1 && <div className='odd'>{item1}</div>}
{item2 && <div className='even'>{item2}</div>}
</div>
)}
</div>
);
}
}
// Render it
ReactDOM.render(
<App />,
document.getElementById("react")
);
.block {
border: 1px solid gray;
}
.odd {
color: red;
}
.even {
color: blue;
}
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
use the entire array not the current iteration
Testimonial in each iteration of the map is a single object. Whereas testimonialContent is the entire array.
{testimonialContent.map((testimonial, i) => {
return (
<Carousel.Item className={classes.carousel_item}>
<div className={classes.root}>
<div className={classes.testimonial_card}>
{testimonial[i]}
</div>
{/* Second card */}
<div className={classes.second_card}>
{testimonialContent[i+1]} // this is the line to change
</div>
</div>
</Carousel.Item>
But something feels very off here. I think you might have an x y problem
Why would you want to use the next iteration as the current iteration? The last item will fail because it doesn't exist and the value of the first testimonialContent will never be shown because you're always starting from index 1.
I would rethink what you're doing here and maybe take another approach.
testimonial is not an array, but the current iterated item in that array. For the "next" item you can use the array testimonialContent.
From the comment I learn that you want to actually produce n/2 rows, so that each item only occurs once. In that case using a plain .map() is not good as it will generate as many rows, and you only need half that number of rows. Instead, you could generate an array with half the number of rows (rounded upwards) with Array.from and use the callback argument of that method.
Array.from({length: (testimonialContent.length+1)>>1}, (_, i) => {
return (
<Carousel.Item className={classes.carousel_item}>
<div className={classes.root}>
<div className={classes.testimonial_card}>
{testimonialContent[i*2]}
</div>
{/* Second card */}
<div className={classes.second_card}>
{testimonialContent[i*2+1] || ""}
</div>
</div>
</Carousel.Item>
)
})
Refer to the testimonial instance in your first div and to the element on the i-th +1 palce in your testimonialContent array in your seccond div.
{testimonialContent.map((testimonial, i) => {
return (
<Carousel.Item className={classes.carousel_item}>
<div className={classes.root}>
<div className={classes.testimonial_card}>
{testimonial}
</div>
{/* Second card */}
<div className={classes.second_card}>
{testimonialContent[i+1]}
</div>
</div>
</Carousel.Item>
This is where I should probably add something to fix the issue, I am stuck with this index that returns the whole object, my goal is to print the index of clicked item, please someone help
const listItems = this.state.list.map((item, index) =>
Object.values(item).map(nestedItem => (
<div>
<Card.Header>
{nestedItem.title}
</Card.Header>
<div class="ui buttons fluid">
<button
onClick={() => this.upvote(index)}
>
UPVOTE
</button>
</div>
))
);
The code below is working correctly it's just that I hard coded the index I am looking for 2 in this example
console.log(Object.keys(this.state.list[index])[2]);
And this is the whole object, all I need now is the index of it
0: "-LORYsI9mLP8mu_2BTKS"
1: "-LORZVOq8SMUgTOPgpXK"
2: "-LORZtqZeg3nyOW4p9I1"
3: "-LOYbElg81jbPtao2nl4"
4: "-LOZ3pNNMAOtNxMWNDi4"
Do you just need the index of the inner mapping? I'm confused by the question still, but perhaps something like this.
const listItems = this.state.list.map((item, index) =>
Object.values(item).map((nestedItem, nestedIndex) => (
<div>
<Card.Header>
{nestedItem.title}
</Card.Header>
<div class="ui buttons fluid">
<button
onClick={() => this.upvote(index, nestedIndex)}
>
UPVOTE
</button>
</div>
))
);
If this doesn't work, could you post an example of your data structure?
here are the docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Syntax
If you want the indices for the nested items, the you'll need to have another variable in the map fn
Object.values(item).map((nestedItem, nestedIndex) => <div>...</div>
and then use the nestedIndex variable in your upvote method
What i want to do is make the items of the list clickable so that once i click on one of them it redirects me to another component for example if i am in /Answers i want to be redirected to /Answers/idOfitemClicked. How can i do that?
Here is the code of my render method:
render() {
const quesItems = this.state.questions.map((question, i) => {
return (
<li key={this.props.account.id === question.expID}>{question.description}
{question.senderID}</li>
);
});
return (
<div>
<h1> Answer the questions here!</h1>
<ul>
{quesItems}
</ul>
</div>
);
}
In your HTML, try having an href=/Answer/idOfItemClick in the item you are trying to make "clickable". In this case <ul>
Simply use html link element with href:
const quesItems = this.state.questions.map((question, i) => {
return (
<li key={this.props.account.id === question.expID}>
<a href={'/Answer/' + question.id}>
{question.description} {question.senderID}
</a>
</li>
);
});