React: Map data horizontally - javascript

I have some data that I am mapping into cards. By default they are mapped vertically under each other (see the screenshot below). However, I would like them to be mapped horizontally next to each other. Is there a way to achieve this?
Here is my code:
return (
<div>
{this.state.serials.map((number) => {
return number.s && number.s.length? (
<div>
<Card className="card" style={{ width: '18rem' }}>
<Card.Body>
<div className="row">
<div className="col">
<h2>{number.s[0].l}</h2>
</div>
<div className="vl"></div>
<div className="col">
<h4>{number.s[0].d[0]}</h4>
{number.s[0].ta}
<FontAwesomeIcon onClick={()=>this.deleteCard(number.s[0].ta)} icon={faTrashAlt} />
</div>
</div>
</Card.Body>
</Card>
<p></p>
</div>
) : null
})}
</div>
);
Thanks in advance!

If you mean you want to put the Card in
X Y Z
instead of
X
Y
Z
then I would recommend putting a container with a display: flex
return (
<div class="container" style={{display: "flex"}}>
{this.state.serials.map((number) => {
return number.s && number.s.length? (
<div>
<Card className="card" style={{ width: '18rem' }}>
<Card.Body>
<div className="row">
<div className="col">
<h2>{number.s[0].l}</h2>
</div>
<div className="vl"></div>
<div className="col">
<h4>{number.s[0].d[0]}</h4>
{number.s[0].ta}
<FontAwesomeIcon onClick={()=>this.deleteCard(number.s[0].ta)} icon={faTrashAlt} />
</div>
</div>
</Card.Body>
</Card>
<p></p>
</div>
) : null
})}
</div>
);

Try setting "flex-direction: row" on outer div (above the map function) or provide more info about "this.state.serials" data...
Example
.container{
display: flex;
flex-direction: row;
}

Related

Map function not displaying data properly

I use to Map method to display data form API but data is not aligned properly I apply reverse method to reverse data but reverse is not working properly
I create this function to display data:
const blogCategory = (item) => {
return(
<>
<div>
<div key={item.title} className="mx-3" style=
{{display:"flex",justifyContent:"center",height:"750px"}}>
<div className="blog bolg-post">
<div className="img-hover-zoom">
<Link href={`/blogs/${item.title.replace(urlR,"-").replace('?',"")}`}>
<img style={{cursor:"pointer"}} className="blog-box" src={item.urlToImage}/>
</Link>
</div>
<div className="d-flex flex-column">
<span className="name-blog">{item.category}</span>
<Link href={`/blogs/${item.title.replace(urlR,"-").replace('?',"")}`}>
<span style={{cursor: "pointer",textAlign:"justify",maxHeight:"62px",overflow:"hidden"}} className="heading-blog">{item.title}</span>
</Link>
<div style={{height:"100px",overflow:"hidden",textAlign:"justify"}} className="para-blog">{item.meta_description}</div>
{/* <div style={{height:"100px",overflow:"hidden",textAlign:"justify"}} className="para-blog" dangerouslySetInnerHTML={{ __html: item.content }}/> */}
<Link href={`/blogs/${item.title.replace(urlR,"-").replace('?',"")}`}>
<button className="btn-blog mt-3">{item.readingTime} min read</button>
</Link>
</div>
</div>
</div>
</div>
</>
)
}
I use Map method to display data by using this function as show in below:
<div className='d-flex col-12' style={{width:"1000px"}}>
<div style={{height:"650px",overflow:'hidden'}}>
{cat.filter(categ=>categ.category === 'technology').reverse().map(
blogCategory
)}
</div>
<div className="products">
{cat.filter(categ=>categ.category === 'technology').map(
productCategory
)}
</div>
</div>
Data is displaying properly but does not align like [0,1,2,3,4,5,6,7,8,9] it displays like [9,8,7,6,5,4,3,2,1,0] .

Handling onClick for a particular element in react

I am trying to make a card grid where the user can expand the card to view its details. The issue I am facing with the react hooks is that the function is getting called for all cards instead of the particular card I am clicking the button. As a result, all the cards are getting expanded.
Here's my code for reference.
Any help is highly appreciated. Thank you!
function Album(props) {
return (
<div>
<Card className={classes.card}>
<Card.Text >
<p className={classes.heading}>
{props.blogTitle}
</p>
</Card.Text>
<Card.Body>
<Card.Img
src={props.imgsrc}
alt="Card image"
className={classes.cardMedia}
/>
{props.cardOpen &&
<AnimatePresence>
<motion.div
initial={{opacity:0}}
animate={{opacity:1, transition:0.3}}
>
<p className={classes.desc} gutterbottom>
{props.blogDescription}
</p>
<div href={props.blogLink}
style={{color:"gray", fontSize:17, fontFamily:"calibri", fontSmooth: "auto", cursor:"pointer", display:"flex", justifyContent:"center"}}>
<LocalLibraryIcon style={{marginRight:7}}/>Read blog
</div>
</motion.div>
</AnimatePresence>
}
{(props.cardOpen) ?
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandLessIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div> : (
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandMoreIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div>
)}
</Card.Body>
</Card>
</div>
);
}
export default function ProjectItems() {
const [cardOpen, setCardOpen]= useState(false);
return (
<React.Fragment>
<CssBaseline />
<main>
<div className={classes.heroContent}>
<Container maxWidth="md">
<Typography
variant="h2"
align="center"
color="textPrimary"
className={classes.root}
gutterBottom
>
Blogs
</Typography>
</Container>
</div>
<Container maxWidth="md">
<Grid container spacing={4}>
{blogData.map(post => (
<Grid item xs={12} sm={6} md={4} key={post.id}>
<div>
<Album
blogId={post.id}
blogTitle={post.title}
blogDescription={post.summary}
imgsrc={post.image_link}
blogLink={post.article_link}
isOpen={()=>{
setCardOpen(!cardOpen);
}}
cardOpen={cardOpen}
/>
</div>
</Grid>
))}
</Grid>
</Container>
</main>
</React.Fragment>
);
}

How to build a simple chart in React based on data from API response

I would like to build a simple chart in React using Nivo library to represent percentage values from data in API response.
The data from the response looks like this: https://run.mocky.io/v3/7c46c4ce-09c0-4f95-b4e1-84ae10bd24ab
I need to represent this data in a really simple line chart.
So far I have this code in my component:
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {useParams} from 'react-router-dom';
import Loader from '../Components/Loader';
import { Bar } from "#nivo/bar";
function ArtistDetail() {
const {artist_uuid} = useParams()
const url = `https://run.mocky.io/v3/${artist_uuid}`;
const [artist, setArtist] = useState({
loading: false,
data: null,
error: false
})
let content = null;
useEffect(() => {
setArtist({
loading: true,
data: null,
error: false
})
axios.get(url)
.then(response => {
setArtist({
loading: false,
data: response.data,
error: false
})
})
.catch(() => {
setArtist({
loading: false,
data: null,
error: true
})
})
}, [url])
if(artist.error) {
content = <p>There was an error loading an artist.</p>
}
if(artist.loading) {
content = <p><Loader/></p>
}
if(artist.data) {
content =
<main className="main">
<section className="section section-artist-detail trending claimed">
<div className="page">
<div className="col visual">
<figure>
<img src= {artist.data.data.image}/>
<figcaption>
<button className="btn btn-claim-music-id">Claim music_id</button>
</figcaption>
</figure>
</div>
<div className="col-wrapper">
<div className="col info">
<div className="col-content">
<div className="info-wrapper">
<div className="title-wrapper">
<button className="btn btn-solid border btn-booking-request">Booking Request</button>
<h1 className="title">
{artist.data.data.name}
<div className="tooltip-wrapper">
<span className="profile-claimed">Profile claimed</span>
<div className="tooltip">
<h3>Vote for subgenres</h3>
<p>Don’t agree with the subgenres? Add the ones you think are missing or vote for existing to get yours on top!</p>
<div className="stats-sheet">
{artist.data.data.subgenres.map(subgenre => {
const {name, score} = subgenre;
return (
<div className="row" key={name, score}>
<h5>{name}</h5>
<div className="graph-line">
<span className="line" style= {{width: score + '%'}}>{score}%</span>
</div>
</div>
);
})}
</div>
<p>
<button className="btn btn-shadow">Vote now</button>
</p>
</div>
</div>
<span className="trending-icon">Trending</span>
</h1>
</div>
<div className="row">
<button className="btn btn-save long">Follow</button>
<button className="btn btn-share">
Share
<span>Link copied to clipboard</span>
</button>
</div>
<div className="row">
<label>Origin</label>
<a className="btn btn-filter-tag">{artist.data.data.country.name}</a>
</div>
<div className="row">
<label>Genre</label>
<span className="btn btn-filter-tag">{artist.data.data.genre.name}</span>
</div>
<div className="row">
<label>Subgenres</label>
{artist.data.data.subgenres.map(subgenre => {
const {name} = subgenre;
return (
<span key={name} className="btn btn-filter-tag">{name}</span>
);
})}
<div className="tooltip-wrapper">
<button className="btn btn-add">Add subgenre</button>
<div className="tooltip">
<h3>Vote for subgenres</h3>
<p>Don’t agree with the subgenres? Add the ones you think are missing or vote for existing to get yours on top!</p>
<div className="stats-sheet">
{artist.data.data.subgenres.map(subgenre => {
const {name, score} = subgenre;
return (
<div className="row" key={name, score}>
<h5>{name}</h5>
<div className="graph-line">
<span className="line" style= {{width: score + '%'}}>{score}%</span>
</div>
</div>
);
})}
</div>
<p>
<button className="btn btn-shadow">Vote now</button>
</p>
</div>
</div>
</div>
</div>
<div className="footer-detail">
<ul className="social-list">
{artist.data.data.social_links.map(item => {
const {channel, link} = item;
return (
<li key={channel, link}>
<a href= {link} className= {`btn social-icon ${channel}`}>{channel}</a>
</li>
);
})}
</ul>
<div className="tooltip-wrapper">
<button className="btn btn-add">Add links</button>
<div className="tooltip">
<h3>Got more info?</h3>
<p>Add Place's links so everyone can see their social media highlights.</p>
<p>
<button className="btn btn-shadow">Add links</button>
</p>
</div>
</div>
</div>
</div>
</div>
<div className="col stats">
<div className="col-content">
<Bar
width={600}
height={400}
margin={{ top: 60, right: 80, bottom: 60, left: 80 }}
data={artist.data.data.popularity}
indexBy="city"
keys={["percentage"]}
labelTextColor="inherit:darker(1.4)"
enableGridX={false}
layout="horizontal"
maxValue={10}
axisTop={null}
axisRight={null}
axisBottom={null}
axisLeft={null}
enableGridX={false}
enableGridY={false}
isInteractive={false}
/>
<div className="stats-sheet">
<label>Most popular in</label>
{artist.data.data.popularity.map(popular => {
const {city} = popular;
return (
<div className="row" key={city}>
<h5>{city}</h5>
<div className="graph-line">
<span className="line" style={{width: 47 + '%'}}>47%</span>
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
<button className="btn btn-scroll-down">Scroll down</button>
</div>
</section>
</main>
}
return (
<div>
{content}
</div>
)
}
export default ArtistDetail;
I have no idea how to display the percentage data inside this div:
<div className="graph-line">
<span className="line" style={{ width: 47 + "%" }}>
47%
</span>
</div>;
It looks like this
For the chart I used the code from here
Good work!
Based on Nivo documentation, I'd try with this
<ResponsiveBar
data={data.popularity}
keys={[ 'city', 'percentage' ]}
maxValue={100}
...
>
..setting maxValue in or to 100 for percentages. Passing data.popularity or artist.data.data.popularity to data attribute and setting up appropriate keys.
{artist.data.data.popularity.map(popular => {
const {city} = popular;
Here might be the problem - destructure both 'city' and 'percentage' from 'popular'.
const { city, percentage } = popular
then
<span>{percentage}%</span>
Looking at the design instead of Nivo you can actually use simple css .Below is the code in which I have used flex to achieve that.
CodeSandbox Link
<div className="App">
<h1>Most Popular in</h1>
{popularity.map((popular) => (
<div>
<div>{popular.city}</div>
<div className="linear-graph">
<div
style={{
background: "black",
flex: popular.percentage
}}
/>
<div
style={{
background: "#c5c5c56b",
flex: 10 - popular.percentage
}}
/>
</div>
</div>
))}
</div>
and the css for that
.App {
font-family: sans-serif;
color: black;
}
.linear-graph {
width: 200px;
display: flex;
position: relative;
height: 6px;
margin-bottom: 10px;
}
Cheers

Several ternary operators nested within

There is a syntax error {} when I added {this.state.items && this.state.items.length? under <div className =" container ">. When I remove this extreme condition {this.state.items && this.state.items.length? : Components : <Preloader />everything works.A lot of nesting and I don't know exactly where the problem is. I think it is an extreme condition. Instead of the main component on the whole page I want to render the preloader on the whole page
class Items extends Component {
render () {
return (
<div className="container">
{this.state.items && this.state.items.length ?
<div className="items">
<div className="item">
<span>
<i></i>
</span>
<h4></h4>
<div className="select">
<button></button>
</div>
</div>
<div className="section">
<input/>
<span>
<i></i>
</span>
</div>
<div>
'AAAAAAA'
</div>
<div className="scroll">
{this.state.items.length === 0 && this.state.status === 1 ?
<div className="array">
<p>AAAAAA</p>
</div>
:
this.state.items && this.state.items.length ?
this.state.items.map((todo, index) =>
<Item
key={item.id}
index={index}
/>
)
:
<div className="preloader">
</div>
}
</div>
</div>
<div className="another">
<Component1
/>
<Component2
/>
</div>
:
<Preloader />
</div>
)
}
}
You were missing an } before the last div to close the first ternary and you were missing a wrapping tag for the first ternaries first expression (I used a React.Fragment). Code snippet bellow should be syntactically correct. I do recommend you refactor your code though.
class Items extends Component {
render() {
return (
<div className="container">
{this.state.items && this.state.items.length ? (
<React.Fragment>
<div className="items">
<div className="item">
<span>
<i></i>
</span>
<h4></h4>
<div className="select">
<button></button>
</div>
</div>
<div className="section">
<input />
<span>
<i></i>
</span>
</div>
<div>'AAAAAAA'</div>
<div className="scroll">
{this.state.items.length === 0 && this.state.status === 1 ? (
<div className="array">
<p>AAAAAA</p>
</div>
) : this.state.items && this.state.items.length ? (
this.state.items.map((todo, index) => (
<Item key={item.id} index={index} />
))
) : (
<div className="preloader"></div>
)}
</div>
</div>
<div className="another">
<Component1 />
<Component2 />
</div>
</React.Fragment>
) : (
<Preloader />
)}
</div>
);
}
}

Add Remove Class on Scroll ReactJs

I am stuck in this problem. I want to add/remove the class on a header element on scroll, but somehow I can not manage it.
I tried to mount and unmount (found few solutions here on Stack) but does not work in my case. Simply because in most of those cases the code relates to component but I have a little bit different set-up.
Here the full code:
https://codesandbox.io/s/angry-villani-lduor?fontsize=14
I want to add the new class on store_details_header
const handleChangeIndex = index => {
setValue(index);
};
if (!selectedStore) {
return null;
}
return (
<div className="store-details">
<div className="store-details__header" style={{ backgroundImage: `url(${selectedStore.headerBackgroundImgUrl})` }}>
<img className="store-details__header__exit" src={exit} alt="exit" onClick={backToNearYou} />
<img className="store-details__header__logo" src={selectedStore.headerLogoUrl} alt="logo" />
</div>
<div className="store-details__content" style={{ backgroundImage: `url(${selectedStore.contentBackgroundImgUrl})` }}>
<div>
<AppBar className={props.classes.root} position="static" color="default">
<Tabs value={value} classes={{ indicator: props.classes.indicator }} onChange={setSelectedNavigationItem} variant="fullWidth">
<StyledTab label="Products" />
<StyledTab label="Items" />
</Tabs>
</AppBar>
<SwipeableViews axis={'x'} index={value} onChangeIndex={handleChangeIndex}>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
</SwipeableViews>
</div>
</div>
{guestMode && renderGuestModeBox()}
{selectedStore.loyaltyCard && renderLoyaltyCard()}
</div>
);
};
const handleChangeIndex = index => {
setValue(index);
};
if (!selectedStore) {
return null;
}
return (
<div className="store-details">
<div className="store-details__header" style={{ backgroundImage: `url(${selectedStore.headerBackgroundImgUrl})` }}>
<img className="store-details__header__exit" src={exit} alt="exit" onClick={backToNearYou} />
<img className="store-details__header__logo" src={selectedStore.headerLogoUrl} alt="logo" />
</div>
<div className="store-details__content" style={{ backgroundImage: `url(${selectedStore.contentBackgroundImgUrl})` }}>
<div>
<AppBar className={props.classes.root} position="static" color="default">
<Tabs value={value} classes={{ indicator: props.classes.indicator }} onChange={setSelectedNavigationItem} variant="fullWidth">
<StyledTab label="Products" />
<StyledTab label="Items" />
</Tabs>
</AppBar>
<SwipeableViews axis={'x'} index={value} onChangeIndex={handleChangeIndex}>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
<TabContainer>
{' '}
<div className="store-details__content__items">{renderSliderItems()}</div>
</TabContainer>
</SwipeableViews>
</div>
</div>
{guestMode && renderGuestModeBox()}
{selectedStore.loyaltyCard && renderLoyaltyCard()}
</div>
);
};

Categories