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) => {
Related
i use usestate to create saveImages and setSaveImages, this initial as array, i want to each time i call the function, the content is different, so each time must to push to the array that info, but instead of do push, only replace the 1 position of array, doesnt add new position with different info. I don't know if I explain myself
const galery = useSelector((state) => state.search);
const dispatch = useDispatch();
const [saveImages, setSaveImages] = useState([]);
function savePhoto(e) {
e.preventDefault();
const { target } = e;
const content = target.photo.src;
setSaveImages(content)
console.log(content)
localStorage.setItem("img", saveImages);
dispatch(actionAddFavorite(content));
}
return(
<section className="w-full gap-0 sm:columns-2 md:columns-3 xl:columns-4 2xl:columns-5 3xl:columns-6">
{galery.map((item, index) => {
return (
<form onSubmit={savePhoto} key={index} className="relative">
<button className="bg-gray absolute left-5 top-3 shadow-md">
Guardar
</button>
<img
name="photo"
className="object-cover p-2"
src={item.urls.regular}
alt={item.alt_description}
/>
</form>
);
})}
</section>
)
You set your saveImages to contain "content", but what you want is to add "content" to existing saveImages array. Here is how you can do this:
setSaveImages(oldImages => {
return [...oldImages, content];
});
And here you can learn everything you need to know about state in react
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>
);
}
After sending a to an API with a 'search value' that searches the database for the value and respond with data containing the value. I want to highlight the given word or search value in the response. The respond is populated to the UI
<center>
{Object.keys(Disp).map((key, i) => (
<center key={i} className="PublicationCard">
<span> {key}</span>
<a href={"https://www." + Disp[key]}> View Publication</a>
</center>
))}
</center>
The Key is a sentence but I want to bolden a word in the key
For example, let say the key is "Discussions about Supervised Artificial Intelligence" and the search query was artificial intelligence, all I want to do is to bold the search query that is "artificial intelligence' in the UI
Maybe you can create a function to generate multiple span tags.
function GenerateSpan({ text, search }) {
const reg = new RegExp(`(.*)(${search})(.*)`, "g")
const array = [...text.matchAll(reg)]
if (array.length > 0) {
return array[0].slice(1).map((textPart, index) => {
return <span key={index} className={textPart === search ? "highlight" : ""}>{textPart}</span>
})
} else {
return <span>{text}</span>
}
}
And use in your code :
<GenerateSpan text=key search="Supervised"/>
And then add style for class "highlight
.highlight{
font-weight: bold
}
So Finally :
<center>
{Object.keys(Disp).map((key, i) => (
<center key={i} className="PublicationCard">
<GenerateSpan text=key search="Supervised"/>
<a href={"https://www." + Disp[key]}> View Publication</a>
</center>
))}
</center>
The example with RegExp works faster, but here is a simpler way.
function Highlighter({ highlight = '', children: text }) {
const index = text.toLowerCase().indexOf(highlight.toLowerCase());
if (index >= 0 && highlight.length) {
const beforeHighlight = text.substring(0, index);
const highlightedPart = text.substring(index, index + highlight.length);
const afterHighlight = text.substring(index + highlight.length);
return (
<highlight-text>
{beforeHighlight}
<span>{highlightedPart}</span>
{afterHighlight}
</highlight-text>
);
}
return <>{text}</>;
}
export default Highlighter;
And use it like:
<Highlighter highlight={'Recursion'}>
{'Recursion a misunderstood topic'}
</Highlighter>
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>
)
}
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>