Render images in Array - arrays

I've a JSON Schema which has Array of images which I need to render into a carousel in ReactJS.
api.json
[
{
"id": "DR001",
"propertyFullName": "8838, Brook St, NY",
"propertyShortName": "Anchorage, AK 99501",
"features": ["2 beds", "1 bath", "865 sqft"],
"description": "data.",
"images": [
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide1",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide2",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide3",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide4",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide5",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide6"
],
"status": true
},
{
"id": "DR002",
"propertyFullName": "8838, Brook St, NY",
"propertyShortName": "Anchorage, AK 99501",
"features": ["2 beds", "1 bath", "865 sqft"],
"description": "data.",
"images": [
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide1",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide2",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide3",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide4",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide5",
"http://placehold.it/1000x400/ffffff/c0392b/&text=slide6"
]
}
]
I am hard-coding the first array i.e. features like this
{APIData.map((apiData, index) => {
return (
<>
<Heading subtitle>
<span name={index}>{apiData.features[0]}</span>
<span class="middle-dot" aria-hidden="true">
</span>
<span>{apiData.features[1]}</span>
<span class="middle-dot" aria-hidden="true">
</span>
<span>{apiData.features[2]}</span> <br />
<span>
<p>{apiData.description}</p>
</span>
</Heading>
<hr />
</>
);
})}
Because, I know there will be only 3 features, but in case of images, it is dynamic. How come I overcome this?
The images are rendering in an other <div>, I've tried something like this
<Carousel {...settings}>
{APIData.map((images, index) => {
return (
<>{<img src={images.images} alt={index} />}</>
);
})}
</Carousel>

Using the code you already had, it will end up something like this to iterate through the images for every property:
<Carousel {...settings}>
{APIData.map((data, index) => {
data.images.map((image, index) => {
return <img key={index} src={image} alt={index} />
}
})}
</Carousel>

You can have a stateless component and render it inside the original map, like this
const Images = ({list}) => list.map(image => <img src={image}/>);
myArr.map(item => // some DOM here, and, at last: <Images list={item.images}>)
You know, not to repeat a map call inside another one, which, in my opinion, looks a bit ugly

Related

React / Make a photo grid with color square under each photograph

Hello
I am trying to implement a photogrid from a json file.
Displaying the photographs is ok, but I can't figure how to display the relative color boxes under each photograph
Here is an extract of my json file :
"images": [
{
"name": "1020.jpg",
"palette": [
"#b43f45",
"#1c2c6c",
"#e5c8c0",
],
"tags": [0,3],
"prompt": "retro 1980 computer tech character"
},
In this case the idea is puting under thr photograph three boxes with the mentioned color.
Here is my code working :
import myjson from "./refs.json";
import PickColor from "./PickColor";
function App() {
const images = myjson.images;
return (
<div>
<div className="gallery">
{images.map((index, i) => {
return <img src={`./images/${index.name}`} key={i} alt="" />;
})}
</div>
</div>
);
}
I have trouble looping for the color palette (should it be nested inside the first callback ) and passing the right color information to a div
EDIT 01
I have tried this solution. Compiling is ok but no result.
<div className="gallery">
{images.map((index, i) => {
return (
<div>
<img src={`./images/${index.name}`} key={i} alt="" />
{index.palette.map((index, i) => {
return (<div className="colorBox" style={{backgroundColor:`"${index[i]}"`}} />);
})}
</div>
);
})}
</div>
I guess the problem is inside the style attribute (by the way I have learned I needed double curly brackets for that) where I tried to access these color information.
"images": [
{
"name": "1020.jpg",
"palette": [
"#b43f45",
"#1c2c6c",
"#e5c8c0",

How to iterate and extract single objects from an array of objects to render in React

I'm getting some data from an API that's coming as an array of objects and want to extract them and destructure them so I can use them to render a component in React. I have achieved something somewaht but this way I'm not KISS and also to render it is creating the item 6 times for each one of them so I have 24divs.
Data is coming like this, "hourly" array with 48 objects. I already slice the array to only use six as that all I need.
"hourly": [
{
"dt": 1618315200,
"temp": 282.58,
"feels_like": 280.4,
"pressure": 1019,
"humidity": 68,
"dew_point": 276.98,
"uvi": 1.4,
"clouds": 19,
"visibility": 306,
"wind_speed": 4.12,
"wind_deg": 296,
"wind_gust": 7.33,
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"pop": 0
},
...
This is what I got inside my return and within section tags which does work but I don't think is the best way to do it, also it's a nightmare to style it properly as it creates six items each time:
<div className="weather-info-extra">
{shortedArr.map((i, index) => (
<div key={index}>
{new Date(i.dt * 1000).toLocaleTimeString([], {
timeZone: timezone,
hour: '2-digit',
minute: '2-digit',
hour12: true,
})}
</div>
))}
{shortedArr.map((i, index) => (
<div key={index}>{i.weather.map(w => w.description)}</div>
))}
{shortedArr.map((i, index) => (
<div key={index}>{i.temp} C</div>
))}
{shortedArr.map((i, index) => (
<div key={index}>
<p>Rain</p>
{i.pop}%
</div>
))}
</div>
I know there's a very obvious way that I'm missing to get each object from the array so I could render it better.
You’re right that you can do this more efficiently. You only need to map once. You can use a fragment to encase the multiple elements, this fragment is never rendered but allows you to have multiple children.
shortArray.map((data, index) => (
<React.Fragment key={index}>
<div>{data.time}</div>
<div>{data.weather}</div>
// anything else you want rendered
<React.Fragment />
));
There’s no need for you to map this array multiple times.
Just a side note, fragments that don't need keys can be written as empty tags in JSX:
<> /** React fragment code here */ </>

How can I get the index of a ordered list in a Rich Text in Contentful (Gastsby)

I'm working on a Gatsby project that uses Contentful as its headless CMS - and rendering a particular rich text field is driving me insane.
This is an example of the document I'm trying to render - It's basically an ordered list:
{
"nodeType": "document",
"data": {},
"content": [
{
"nodeType": "ordered-list",
"content": [
/* item 1 */
{
"nodeType": "list-item",
"content": [
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "text",
"value": "Lorem 1.",
"marks": [],
"data": {}
}
],
"data": {}
}
],
"data": {}
},
/* item 2 */
{
"nodeType": "list-item",
"content": [
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "text",
"value": "Lorem 2",
"marks": [],
"data": {}
}
],
"data": {}
}
],
"data": {}
},
],
"data": {}
}
]
}
And I want to render it on my Gatsby project without it's ol and li tags, like this:
<div class="single-instruction">
<header>
<p>Step 1</p>
<div></div>
</header>
<p>Lorem 1.</p>
</div>
<div class="single-instruction">
<header>
<p>Step 1</p>
<div></div>
</header>
<p>Lorem 2.</p>
</div>
Following Contentful's docs, I'm trying to render this using the #contentful/rich-text-types package. This is how far I managed to get:
import { BLOCKS } from "#contentful/rich-text-types";
import { renderRichText } from "gatsby-source-contentful/rich-text";
const options = {
renderNode: {
[BLOCKS.LIST_ITEM]: (node, children) => (
<div className="single-instruction">
<header>
<p>step </p>
<div></div>
</header>
{children}
</div>
),
},
};
renderRichText(instructions, options)
Which, of course, doesn't render the step number.
I feel I'm so close now! But for the life of me, I can't seem to find the right way to render the ordered list item index. Which is something I would easily get if this were an array that I could simple map.
Does anyone know what I'm missing here?
I have been facing the same issue. I used the counter-increment and counter css properties to generate the step numbers.
.instructions {
counter-increment: step;
}
.single-instruction .step::after {
content: counter(step);
}
<div class="instructions">
This is one list
<div class="single-instruction">
<header>
<p class="step"></p>
<div></div>
</header>
children
</div>
<div class="single-instruction">
<header>
<p class="step"></p>
<div></div>
</header>
children
</div>
</div>
<div>
This is another list
<div class="single-instruction">
<header>
<p class="step"></p>
<div></div>
</header>
children
</div>
<div class="single-instruction">
<header>
<p class="step"></p>
<div></div>
</header>
children
</div>
</div>
In this case you could use the CSS counter() variable to add step numbers via CSS.
So your CSS might look something like:
.single-instruction {
counter-reset: section;
}
.single-instruction p:after {
counter-increment: section;
content: counter(section);
}
The code above will add the counter on each paragraph (for the header paragraph content and the actual content paragraphs), so you'll need to add a custom class for the paragraph tags you want to target.
The only caveat is that I'm not sure how well this will work with screen readers and other assistive technology without digging deeper.
More information here: https://www.w3schools.com/CSS/css_counters.asp

React when checkbox checked filter data

on games page if you are search a game, page is redirect to search result page. I want a filter on search result page. When I checked checkbox, data will be filtered.
json format is here
{"id": 26,
"title": "ebirth",
"sortName": "",
"isFullyOptimized": false,
"steamUrl": "",
"store": "",
"publisher": "",
"genres": ["Action", "Simulation"],
"status": "AVAILABLE"}
I have a aside menu component there is checkboxes. I want when I checked checkbox here I filtered by genres and status to my search results. Data returned from search results here
{gameIds.length > 0 && (
<div className="search-result__content">
<div className="search-result__title">
<h2>Search Results</h2>
<span>{data.filter(({ id }) => gameIds.includes(id)).length} results</span>
</div>
<div className="game-card__content">
{data
.filter(({ id }) => gameIds.includes(id))
.map((item, i) => {
return (
<a key={i} href={item.steamUrl} className={item.steamUrl && "has-url" ? "has-url" : ""}>{item.title}</a>
);
})}
</div>
</div>
)}
How can I do this?
Here is the code
https://codesandbox.io/s/strange-bardeen-pf1k0

ReactJS rendering image from array

I am trying to render image from array by placing its name in middle of <img> link.
At this time I have ran out of links that could help me...
I tried everything that came to my mind. Everything displays as it should except image...!
this is array:
cars: [
{
'carname': '2013 Toyota GT86',
'owner': 'Ryan',
'desc': 'Aero Paket, BC Coilover, 3sdm 0.01 black matte, Invidia N1 Catback, Valenti taillights, camouflage vinyls, Vortech supercharger incl. oil cooler - 325hp daily driver',
'image': 'toyota'
}]
Render section:
render() {
const cars = this.state.cars.map((car, i) => {
return (
<div key={i}>
<div className="col-md-12 cBusiness">
<h2>
{ car.carname }
</h2>
<p>Owner: { car.owner }</p>
<p>{ car.desc }</p>
<p>
<img src={"pages/upload/{car.image}.jpg"} />
</p>
</div>
</div>
);
});
structure:
Do something like this:
<img src={`pages/upload/${car.image}.jpg`} />
Try using template literals:
<img src={`pages/upload/${car.image}.jpg`} />
or old skool for all the IE folks out there:
<img src={"pages/upload/" + car.image + ".jpg"} />
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Resources