Loading an array of videos in two columns in React - javascript

I'm trying to get videos to load two videos per row down the page in order and i'm having trouble figuring out how. Currently I have them loading from contentful in one column with this:
const VideoPage = ({ data }) => {
return (
<div>
<Layout>
<Head title="Videos"/>
<div className={videoStyles.container}>
{data.allContentfulVideoEmbed.nodes.map((node) => {
return (
<div>
<div className={videoStyles.videoWrapper}
dangerouslySetInnerHTML={{ __html: node.markdownContent.childMarkdownRemark.html }}
/>
<div className={videoStyles.titles}>
<p>{node.title}</p>
</div>
</div>
);
})}
</div>
</Layout>
</div>
)
}
Does anyone know how to go about this?

Simply throw them into a grid with 2 columns, each looped item will then be placed in corrosponding columns 1 - 2 for each row. For instance with Tailwindcss
const VideoPage = ({ data }) => {
return (
<div>
<Layout>
<Head title="Videos"/>
<div className="grid grid-cols-2">
{data.allContentfulVideoEmbed.nodes.map((node) => {
return (
/**
* Every nth 1 will be column 1
* Every nth 2 will be column 2
*/
<div>
<div className={videoStyles.videoWrapper}
dangerouslySetInnerHTML={{ __html: node.markdownContent.childMarkdownRemark.html }}
/>
<div className={videoStyles.titles}>
<p>{node.title}</p>
</div>
</div>
);
})}
</div>
</Layout>
</div>
)
}

Related

Why does my id i get from next js router.query return undefined on refresh? [duplicate]

This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 5 months ago.
I am using the id gotten from next router.query to render elements dynamically it works when i access the room from next/link but when i refresh the page it throws this error
here is my code (note: roomId here was gotten from const {roomId} = router.query):
return (
<>
<div className={styles.header}>
<div className={styles.title}>{rooms[roomId].name}</div>
<div className={styles.headerCon}>
<div className={styles.roomUsers}>
<AvatarGroup
max={3}
total={Object.keys(rooms[roomId].users).length}
>
{Object.keys(rooms[roomId].users).map((user) => (
<Avatar
key={user + Math.random()}
alt={users[user].name}
src={users[user].profile_pic}
/>
))}
</AvatarGroup>
</div>
<div className={styles.headerIcons}>
<div className={styles.react}>
<AddReactionOutlinedIcon />
</div>
<div className={styles.notif}>
<NotificationsNoneOutlinedIcon />
</div>
<div className={styles.more}>
<MoreHorizOutlined />
</div>
</div>
</div>
</div>
{user.name === rooms[roomId].createdBy.name ? (
<div className={styles.begin}>
{!roomActive ? (
<button onClick={handleStartSession}>Start</button>
) : (
<button onClick={handleEndSession}>End</button>
)}
</div>
) : (
""
)}
<div className={styles.participators}>
<div className={styles.pAvatars}>
<Avatar
alt={rooms[roomId].createdBy.name}
src={rooms[roomId].createdBy.profile_pic}
/>
<div className={styles.userName}>{rooms[roomId].createdBy.name}</div>
<div className={styles.userRole}>Admin</div>
<div>
<audio autoPlay ref={userAudio} />
{peers.map((peer, index) => {
return <Audio key={index} peer={peer} />;
})}
</div>
</div>
{Object.keys(rooms[roomId].users)
.filter((user) => users[user].name !== rooms[roomId].createdBy.name)
.map((user) => (
<div className={styles.pAvatars} key={Math.random() + user}>
<Avatar alt={users[user].name} src={users[user].profile_pic} />
<div className={styles.userName}>{users[user].name}</div>
<div className={styles.userRole}>Admin</div>
</div>
))}
</div>
</>
);
}
As you can see much of what i am rendering on this page depends on that id, so can someone please help?
You try to access the query parameter before its state is ready. There is a workaround to solve this problem.
import { useRouter } from 'next/router';
const router = useRouter();
useEffect(() => {
if (router.isReady) {
// Do your stuff
// for example: assign query param to a state
}
}, [router.isReady]);

Introduce a div between a loop to add flex

This is what I currently have which displays fine.
I end up with 4 rows and 4 columns.
<div>
{(
<Table
data={{
body: Object.keys(conduitData).map((key) => {
const conduitArray = conduitData[key];
return conduitArray.map(category => ({
content:
<div>
<ConduitSelector
data={{title: category.name}}
/>
</div>
}));
}),
}}
/>
)}
</div>
But the CSS does not wrap and the content keeps squeezing into the same row.
I want it to flex down if there is more than 3 items in a row.
I want to be able to wrap each row into another div so that I could introduce flex css properties as follows:
conduitData is a map.
conduitArray is an array.
<div>
{(
<Table
data={{
body: Object.keys(conduitData).map((key) => {
const conduitArray = conduitData[key];
// (parent) I want to add this div to introduce css flex
return <div style={{display: 'flex'}}>
{conduitArray.map(category => ({
content:
// adding flex properties here too
<div style={{flex: '0 0 33.333333%'}}>
<ConduitSelector
data={{title: category.name,}}
/>
</div>,
}))}
</div>
}),
}}
/>
)}
</div>
But when I run this, I end up with the following error.
Error!row.map is not a function
Is there a way I could overcome this error?
I dont see why you cant put the styles in the surrounding your Table.
<div style="display: flex; flex-wrap: wrap;">
<conduit div style="flex-basis: 33.333333%">
</div>
</div>
EDIT
maybe wrap around the return function instead?
return <div>{ conduitArray.map(category => ({
content:
<div>
<ConduitSelector
data={{title: category.name}}
/>
</div>
})) }</div>;

React; Why does my array.map method render only one element from an array?

I am trying to render a component multiple times based on an array passed on from the parent component. But the child component gets whole array as property so does not render correctly. Can I get any tips on that?
App.js
function App() {
const [businesses, setBusinesses] = useState([]);
function searchYelp(term, location) {
Yelp.search(term, location)
.then((businessesList) => {
setBusinesses([businessesList]); // this should be updated to setBusinesses(businessesList)
})
.then(console.log(businesses));
}
console.log(businesses);
return (
<div>
<Hero>
<SearchBar searchYelp={searchYelp} />
</Hero>
<Layout>
<BusinessList businesses={businesses} />
</Layout>
</div>
);
}
BusinessList.js
const BusinessList = ({ businesses }) => {
return (
<div>
<h2 className="business-list__header">İşletmeler</h2>
<div className="business-list">
{businesses.map((business) => {
return <Business business={business} key={business.id} />;
})}
</div>
</div>
);
};
Business.js
const Business = ({ business }) => {
return (
<div className="business">
<div className="business__image-container">
<img src={business.imageSrc} alt="İşletme Görseli" />
</div>
<div className="business__information">
<h2 className="business__header">{business.name}</h2>
<div className="business__address">
<p className="business__address-text">{business.address}</p>
<p className="business__address-text">{business.city}</p>
</div>
<div className="business__reviews">
<h3 className="business__reviews-header">{business.category}</h3>
<h3 className="business__rating">{business.rating}</h3>
</div>
</div>
</div>
);
};
Any tips would be greatly appreciated.
You can see the values components get below.
Child Component
Extended Parent Component

React rendering a loop inside a loop

Trying to loop inside a loop and getting error: value.forEach is not a function.
Dont know how to write this code inside a render
render(){
return(
Object.entries(this.props.detailOras).map(([key, value])=>{
return(
<div className="flex-row">
<div className="flex-cont">
<div>Laikas</div>
<div>Temperatūra </div>
<div>Vėjas</div>
<div>Krituliai</div>
</div>
{value.forEach(day => {
return(
<div className="flex-cont">
<div>{day.forecastTimeUtc.slice(11,16)}</div>
<div>{day.airTemperature} </div>
<div>{day.windSpeed}</div>
<div>{day.totalPrecipitation}</div>
</div>
)
})}
</div>
)
}
))}
Below should work provided value is populated as an array in later stages.
render(){
return(
Object.entries(this.props.detailOras).map(([key, value])=>{
return(
<div className="flex-row">
<div className="flex-cont">
<div>Laikas</div>
<div>Temperatūra </div>
<div>Vėjas</div>
<div>Krituliai</div>
</div>
{(value.forecast || []).map(day => {
return(
<div className="flex-cont">
<div>{day.forecastTimeUtc.slice(11,16)}</div>
<div>{day.airTemperature} </div>
<div>{day.windSpeed}</div>
<div>{day.totalPrecipitation}</div>
</div>
)
})}
</div>
)
}
))}

How to make images fit the page in React/Bootstrap?

I am using a function that maps every item in the props array to creating an image tag. I am trying to make every 3 images have a row div around them using bootstrap so they will fit the page correctly, but I cannot figure out how to do it. Any help would be appreciated. Here is the code:
import React, { Component } from 'react';
import "./Skills.css";
export default class Skills extends Component {
static defaultProps = {
images: [
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/HTML5_logo_and_wordmark.svg/1200px-HTML5_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/CSS3_logo_and_wordmark.svg/1200px-CSS3_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png",
"https://p7.hiclipart.com/preview/306/37/167/node-js-javascript-web-application-express-js-computer-software-others.jpg",
"https://bs-uploads.toptal.io/blackfish-uploads/skill_page/content/logo_file/logo/5982/express_js-161052138fa79136c0474521906b55e2.png",
"https://webassets.mongodb.com/_com_assets/cms/mongodb_logo1-76twgcu2dm.png",
"https://www.pngfind.com/pngs/m/430-4309307_react-js-transparent-logo-hd-png-download.png",
"https://botw-pd.s3.amazonaws.com/styles/logo-thumbnail/s3/012015/bootstrap.png?itok=GTbtFeUj",
"https://sass-lang.com/assets/img/styleguide/color-1c4aab2b.png"
]
}
photo() {
return (
<div >
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
);
}
render() {
return (
<div id="skills-background" className="mt-5">
<div id="skills-heading" className="text-center">Skills I've Learned:</div>
<div className="container">
<div className="row">
{this.photo()}
</div>
</div>
</div>
)
}
}
CodeSandbox
I think, I found the issue,
<div> <-----This div is the issue
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
You have wrapped your col-md-4 with a div, and div has display: block style, so you are getting every image on separate row. Simply replace div with Fragments,
<> <-----Make it Fragment
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</>

Categories