How to make html code as a variable and use it? - javascript

Below is my sample code .....
<ul>
{this.state.showAllUser == false
? someArray.slice(0, 3).map(function(user, index) {
return (
<li key={index}> {user.name}<li>
)
: someArray.map(function(user, index) {
return (
<li key={index}> {user.name}<li>
)
}
</ul>
If this.state.showAllUser is false, i will only show three of array or show all of them if true.
My question is how to make this code more clean , can I make a function or variable and use it in refer function?

You could use the Array method instead, like so:
<ul>
{someArray.filter(function(el, index) {
if (!this.state.showAllUser) {
// Print the first 3 elements
return (index < 3)
} else {
// Print all
return true
}
})
.map(function(user, index) {
return (<li key={index}> {user.name}</li>)
})
}
</ul>
In this way it is very clear where you control which elements are going to be shown and which are not.
And more you write only once the virtual DOM part.

<ul>
{
(this.state.showAllUser == false ? someArray.slice(0, 3) : someArray).map((user, index) => <li key={index}> {user.name}<li>);
}
</ul>

Related

Nested map function returns nothing

i'm currently developing a Dashboard in React.js with MUI.
I have a list of courses and athletes. Every athlete can have multiple course applied for.
For each applied course i want to display a Card with name of the course and the venue.
When i change filter in courseFound to find and return only the first one it works. But when i have a second map function to map the respecting courses, i'll get a blank site.
{
athletes.map((athlete, index) => {
if (athlete.courses.length > 0 && courses.length > 0 && venues.length > 0) {
const courseFound = courses.filter(course => course.athletes.find(athleteInArray => athleteInArray === athlete.id));
courseFound.map((course, index) => {
const venue = venues.find(venue => venue.id === course?.venue);
return (
<div key={index}>
<h3 className={classes.header}>{athlete.firstName + ' ' + athlete.lastName}</h3>
<DashboardGridElement key={index} courseName={course!.name} courseVenue={venue!.venueClubName} courseId={course!.id} />
</div>
);
})
}
})
}
Yeah and my further question is, why i can't put the tag with outside the return? If i do so the return doesn't work anymore?
I'm thankful for any ideas or help.
return (
<Root>
<div className={classes.spacing}>
<h1 className={classes.header}>{t('general', 'navigation', 'dashboard')}</h1>
<>
{
//Future Simon Problem: only one course per person shown in Dashboard grid
athletes.map((athlete, index) => {
const coursesOfAthlete = courses.filter(course => course.athletes.find(athleteInArray => athleteInArray === athlete.id));
<h3 className={classes.header}>{athlete.firstName + ' ' + athlete.lastName}</h3>
return coursesOfAthlete.map((course, index) => {
const venue = venues.find(venue => venue.id === course?.venue);
return (
<div key={index}>
<DashboardGridElement key={index} courseName={course!.name} courseVenue={venue!.venueClubName} courseId={course!.id} />
</div>
);
})
})
}
</>
</div>
</Root >
)
Does anyone has an idea how i get this to work. The thing is, when the is inside the inner map it prints the name every time, but i only wants on name and the the Cards for this name (athlete)
The "outer" .map() operation never returns anything. Perhaps you meant to return the result of the "inner" .map() operation:
return courseFound.map((course, index) => {

Displaying a nested data with a conditional: How can I not display the data whose product's color is not according to the conditional?

I am trying to display all the quantity of colors that are more than 10. It does display it, however, this will also display even the products whose colors are less than 10. How do I fix this? Thank you.
codesandbox: https://codesandbox.io/s/products-0ccdhk?file=/src/App.js:752-1189
{product &&
product.map((item, i) => (
<ul key={i}>
<li>{item.id}</li>
<li>{item.prodName + " " + item.size}</li>
{Object.entries(item.colorMap).map((color) => (
<>
{color[1] > 10 && (
<>
{color[0]} - {color[1]}
</>
)}
</>
))}
</ul>
))}
Currently, this is what it looks like:
{product &&
product.map((item, i) => {
const obj = item.colorMap;
for (let x in obj) {
if (obj[x] > 10) {
return <li key={i}>{item.prodName + " " + item.size}</li>;
}
}
})}
Link CodeSandbox: https://codesandbox.io/s/products-forked-mtt94c?file=/src/App.js:752-1008
Because you used "=> ()" in map method, it returned whole items in your product array. I replaced it as "=> {}" and returned with a condition in "{}".
You can also write like this:
export default function App() {
const newProduct = product.filter((item) => {
return Object.values(item.colorMap).every((color) => color > 10);
});
return (
<ul className="App">
{newProduct &&
newProduct.map((item, i) => (
<li key={i}>{item.prodName + " " + item.size}</li>
))}
</ul>
);
}

React ternary operator with array.map return

In my react render function, I am using array.map to return some JSX code in an array and then rendering it. This doesn't seem to work, I read a few questions here that suggested using return statement inside if/else block but that won't work in my case. I want to check whether round and duration are set on each array element and only then pass it in the JSX code.Could someone tell me a different approach please.
render() {
var interviewProcessMapped = interviewProcess.map((item, index) => {
return
{item.round ?
<div className="row title">
<div className="__section--left"><span className="section-title">Round {index + 1}</span></div>
<div className="__section--right">
<h3>{item.round}</h3>
</div>
</div>
: null
}
{
item.durationHours > 0 || item.durationMinutes > 0 ?
<div className="row">
<div className="__section--left">Duration</div>
<div className="__section--right border">
{item.durationHours > 0 ? <span>{item.durationHours} Hours</span> : null} {item.durationMinutes > 0 ? <span>{item.durationMinutes} Minutes</span> : null}
</div>
</div>
: null
}
});
return <div>{interviewProcessMapped}</div>
}
{ not required here:
return {item.round ?
If you use it that means you are returning an object.
Another issue is alone return means return; (automatic semicolon insertion) so either put the condition in same line or use ().
Write it like this:
render() {
let a, b;
var interviewProcessMapped = interviewProcess.map((item, index) => {
a = item.round ?
<div className="row title">
....
</div>
: null;
b = (item.durationHours > 0 || item.durationMinutes > 0) ?
<div className="row">
....
</div>
: null;
if(!a || !b)
return a || b;
return [a, b];
});
return (....)
}
You should probably use a combination of Array.prototype.map() and Array.prototype.filter()
No need for if at all
Here the pseudo code:
interviewProcess.filter(() => {
// return only if round and duration set
}).map(() => {
// transform the filtered list
});

how to run different array on my map function for my nav component

Pretty new at coding so sorry if my question looks ridiculous...
I am building a menu on my website which is divided in several categories.
In this example, we have Theory and Video categories ( Video only 1 level and Theory is going deeper on 2 levels).
The code below is working for only 1 category at time (thats why the comments).
I would like to ask you how to build a more generic function that can run whatever the array is (for the map function) and avoid this: "Cannot read property 'map' of undefined".
render() {
const theories = this.props.menuTheory;
const videos = this.props.menuVideos;
// const menuTheory = theories.map((theory, i) => (
//
// <div className="nav__category" key={i} onClick={() => this.onSelect(theory.category)}>
//
// <div className={this.state.isSelected === theory.category
// ? "nav__category__dropdown nav__category__dropdown--isSelected"
// : "nav__category__dropdown"}>
// <span className="nav__category__text">{theory.category}</span>
// <span className="checked"><img src={'../static/icons/nav__check.svg'}/></span>
// </div>
// <ul className={this.state.isExpanded === theory.category
// ? "nav__chapterBox"
// : "nav__chapterBox nav__chapterBox--isNotExpanded"}>
// {theory.chapters && theory.chapters.map((chapter, i) => <NavChapter key={i} id={chapter.objectId} title={chapter.name} onClick={() => this.onSelect1(chapter.objectId)}/>)}
// </ul>
// </div>
// ))
const menuVideo = videos.map((video, i) => (
<div className="nav__category" key={i} onClick={() => this.onSelect(video.category)}>
<div className={this.state.isSelected === video.category
? "nav__category__dropdown nav__category__dropdown--isSelected"
: "nav__category__dropdown"}>
<span className="nav__category__text">{video.category}</span>
<span className="checked"><img src={'../static/icons/nav__check.svg'}/></span>
</div>
</div>
))
return (
<nav className="nav__categoryBox">
{/* {menuTheory} */}
{menuVideo}
</nav>
)
}
Thanks.
Okay, so it sounds like you're looking for a way to do conditional rendering in React. What you need to do is add some state to the component. I've added showVideos as a bool (true|false). Use showVideos in the render method to determine which menu to show. You still create the menus using map, but in the return block, check this.state.showVideos to determine which content to return. To get this fully working, you'll also need to add a button that calls toggleMenu onClick that will update your state and switch which menu is being shown.
toggleMenu(){
this.setState({
showVideos: !this.state.showVideos
});
}
render() {
const theories = this.props.menuTheory;
const videos = this.props.menuVideos;
const menuTheory = theories.map((theory, i) => (
<div className="nav__category" key={i} onClick={() => this.onSelect(theory.category)}>
<div className={this.state.isSelected === theory.category ? "nav__category__dropdown nav__category__dropdown--isSelected" : "nav__category__dropdown"}>
<span className="nav__category__text">{theory.category}</span>
<span className="checked"><img src={'../static/icons/nav__check.svg'}/></span>
</div>
<ul className={this.state.isExpanded === theory.category ? "nav__chapterBox" : "nav__chapterBox nav__chapterBox--isNotExpanded"}>
{theory.chapters && theory.chapters.map((chapter, i) => <NavChapter key={i} id={chapter.objectId} title={chapter.name} onClick={() => this.onSelect1(chapter.objectId)}/>)}
</ul>
</div>
))
const menuVideo = videos.map((video, i) => (
<div className="nav__category" key={i} onClick={() => this.onSelect(video.category)}>
<div className={this.state.isSelected === video.category ? "nav__category__dropdown nav__category__dropdown--isSelected" : "nav__category__dropdown"}>
<span className="nav__category__text">{video.category}</span>
<span className="checked"><img src={'../static/icons/nav__check.svg'}/></span>
</div>
</div>
))
return (
<nav className="nav__categoryBox">
<button onClick={this.toggleMenu}>Toggle Menu</button>
{this.state.showVideos ? menuVideo : menuTheory}
</nav>
)
}

checking for first key in map with reactjs

I've got the following component in ReactJS
var MainMenu = React.createClass({
render: function() {
console.log(this.props.groupsData);
var categories = this.props.groupsData.objects.map(function(obj){
return (<li>{obj.display_name}</li>);
});
return (<div className="MainMenu">
<ul className="nav nav-pills">{categories}</ul>
</div>);
}
});
Now, I wish to add className='active' to the <li> element if its the first in the map. How would I achieve this?
Use JS in your expression
var MainMenu = React.createClass({
render: function() {
console.log(this.props.groupsData);
var categories = this.props.groupsData.objects.map(function(obj, index) {
// You can have a JavaScript expression in your expression
return ( <li className={index == 0 ? 'active' : ''}> <a href="#">{
obj.display_name
}</a></li> );
});
return ( <div className="MainMenu" >
<ul className="nav nav-pills" >{
categories
}</ul>
</div> );
}
});

Categories