Display JSON array in react component - arrays

i have Array of image urls:
"image": [
"https://i.imgur.com/QHQaUxi.jpg",
"https://i.imgur.com/GNjH4mZ.jpg",
"https://i.imgur.com/py9IkGa.jpg",
],
my YachtDetailsData looks like this:
{
"id": "1",
"name": "Rarity",
"title": "Modern facilities, sophisticated style and chic deck areas make luxury yacht RARITY one of the most sought-after charter yachts in her class. Her large beam of 10m offers extra onboard space with wide deck areas, making RARITY the ideal yacht tocharter for events such as the Grand Prix",
"description": "The 180'5 / 55m Custom motor yacht 'Rarity' was built in 2008 by Rossi Navi and last refitted in 2017. Officina Italiana Design is responsible for her beautiful exterior and interior design. Previously named Syna, her interior combines timeless styling and beautiful furnishings. She offers large volumes, an open plan Main Salon and dining room, a fully equipped gym and a sky lounge with 220-inch cinema screen. Rarity’s interior layout sleeps up to 12 guests in 6 guest cabins.",
"price": "235.000€",
"guests": "12 guests",
"length": "55 meters",
"build": "2008",
"cabins": "06",
"refit": "2017",
"maxSpeed": "15.5 kt",
"builder": "Rossinavi",
"location": "Mediterranean",
"crew": "12",
"coverImage": "https://i.imgur.com/U7yw2EF.jpg",
"image": [
"https://i.imgur.com/QHQaUxi.jpg",
"https://i.imgur.com/GNjH4mZ.jpg",
"https://i.imgur.com/py9IkGa.jpg",
"https://i.imgur.com/4n3sZxb.jpg",
"https://i.imgur.com/8CbKNUm.jpg",
"https://i.imgur.com/R5eIKmQ.jpg",
"https://i.imgur.com/zEJ8Oxa.jpg",
"https://i.imgur.com/PfuoqQQ.jpg",
"https://i.imgur.com/IgxuEA7.jpg",
"https://i.imgur.com/8GNUaSx.jpg",
"https://i.imgur.com/3kUArby.jpg",
"https://i.imgur.com/1xhp0DT.jpg",
"https://i.imgur.com/flmYnDc.jpg"
],
"video": ""
},
i have got 7 objects with image array and i want do display each image in React image slider:
import YachtDetailsData from "../data/YachtList.json"
interface Props {
match: any
}
const YachtDetails: React.FC<Props> = ({match}) => {
const yachtData = YachtDetailsData.find(yacht => yacht.id === match.params.id)
const slider = (
<AwesomeSlider>
<div><img src={yachtData?.image[]} alt=""/></div>
</AwesomeSlider>
);
i don't no what to do. Do i need to map them? I am beginner so any help is welcome.

Try this..
const YachtDetails: React.FC<Props> = ({ match }) => {
// here im just spreading/pushing the object in an array, so it will make use
// of the `find` method which is an array method.
const newYachtData = [{...YachtDetailsData}]
const yachtData = newYachtData.find(
(yacht) => parseInt(yacht.id) === match.params.id
);
const slider = (
<AwesomeSlider>
<div>
{yachtData?.image.map((image, key) => (
<div key={key}>
<img src={image} alt="" />
</div>
))}
</div>
</AwesomeSlider>
);
};

Related

Render image with json data | ReactJs

So I'm trying to make the addition of project easier for me with a json data.
Basically I'm creating blocks of projects and each project comes with an image, however even when the id == to the name I gave the image, the image does not render. Is there is any option for that or should I just give up on json files ?
what I'm trying to re-do
What I'm actually getting
The reactjs code
import Pdata from "../../api/projects.json";
import p1 from "../../img/Project/PoleAnglais.png";
import p2 from "../../img/Project/I-Art.png";
import p3 from "../../img/Project/Hestia.png";
import p4 from "../../img/Project/EvlV1.png";
import p5 from "../../img/Project/Kelly.png";
import p6 from "../../img/Project/EthLnyV2.png";
import { Component } from "react";
class Plist extends Component {
render() {
return (
<div
className="project-list"
data-aos="fade-right"
data-aos-duration="1200"
>
{Pdata.map((projectDetail, index) => {
return (
<div className="project-block">
<h2 className="project-title">{projectDetail.title}</h2>
<p className="date">{projectDetail.date}</p>
<p className="project-desc">{projectDetail.desc}</p>
<img src={projectDetail.id} alt="" />
<p className="madewith">made with {projectDetail.tags}</p>
</div>
);
})}
</div>
);
}
}
export default Plist;
The json data
[
{
"id": "p1",
"title": "Pole Anglais",
"date": "16/10/2019",
"desc": "This project was in association with Filip Zafirovski, my English teacher by the time who wanted students to get a source of inspiration by publishing articles and/or their work. It was my very first web project, and was kind of hard to pull off but I still enjoyed it.Since for the very first time i coded for a project and not myself.",
"tags": "Loads of crap"
},
{
"id": "p2",
"title": "Project I.Art",
"date": "3/07/2021",
"desc": "In France to go to college you have to get a diploma, which requires multiple exams to be validated. One of the subjects I had to do a presentation on was Art. I decided to create an idea around an Artificial Intelligence who would create art based on the likes and dislikes of the spectator. This panel is a website made for the occasion.",
"tags": "Html,Scss, & AOS librairie"
},
{
"id": "p3",
"title": "Hestia Real Estate",
"date": "18-26/10/2021",
"desc": "At the very start of my student life #hetic, They grouped student randomly to make a project. The subject of the project was to create an agency, a fake web-app and website that sells premium submarines to plus ultra rich people. For that project I designed the website of the agency, and the app for the complex.",
"tags": "Html & Scss"
},
{
"id": "p4",
"title": "EvL First Design",
"date": "30/10/2021",
"desc": "Before the design and dev of this portfolio, I had made a portfolio where I only putted my socials link. All of that because I had no idea of what to put on it. Even if I was satisfied with the first version it did not in any case represented the mood and emotion I wanted it to give. And so I gave birth to the actual design of the website on the 11/11/2021",
"tags": "Nextjs & Scss"
},
{
"id": "p5",
"title": "Kelly's Portfolio",
"date": "3/07/2021",
"desc": "Sometimes after arriving at my college, I met a freshly made friend who wanted to publish her portfolio. She knew how to design and do plenty others thing. To She didn't really like to code and was making her website with Wix. To which I proposed to remake her website by coding it myself.",
"tags": "VueJs & Scss"
},
{
"id": "p6",
"title": "EthLny V2",
"date": "11-12/11/2021",
"desc": "After doing the amazing portfolio of Kelly, I was kind of disappointed with my own. So I decided to remake a new design. Use a Random language, study the color psychology, searched a tagline. And TA-DA here it is, the website you're in right now is the result of 7 hours of researching, designing and coding and debugging.",
"tags": "ReactJs, Scss & AOS librairy"
}
]
Put your images into object, so keys would be ids from json,and values - URLs to your images. Right now you are just passing string like "p1" and "p5" into src. It is not equivalent to passing value of variable with name p1 or p5.
Fast way to create such object would be this:
import p1 from "../../img/Project/PoleAnglais.png";
import p2 from "../../img/Project/I-Art.png";
import p3 from "../../img/Project/Hestia.png";
import p4 from "../../img/Project/EvlV1.png";
import p5 from "../../img/Project/Kelly.png";
import p6 from "../../img/Project/EthLnyV2.png";
let images = {
p1, p2, p3, p4, p5, p6
}
/**
It is same as let images = {p1: p1, p2: p2, p3: p3, p4: p4, p5: p5, p6: p6};
*/
Then, inside your component use id from JSON as a key:
<img src={images[projectDetail.id]} alt=""/>
This way you will get actual value of variable p1 (and others).
I think the image is rendering but it is just too small to see
try adding width and height.
<img style={{width: 200px, height: 200px}} src={projectDetail.id} alt="" />
I think this will solve your problem. instead of importing each image, either create a map that points P* to your image addresses or rename your images in a way that you can do this:
{Pdata.map((projectDetail, index) => {
return (
<div className="project-block">
<h2 className="project-title">{projectDetail.title}</h2>
<p className="date">{projectDetail.date}</p>
<p className="project-desc">{projectDetail.desc}</p>
<img src={`../../img/Project/${projectDetail.id}.png`} alt="" /> // <====the change
<p className="madewith">made with {projectDetail.tags}</p>
</div>
);
})}
you can also add an image prop to your json pointing to the right image, but the json might be out of your hands to change.

How to map through a json object that is stored in a react component not coming from an api?

I have a file inside my react project, glossaryItems.json. The file looks like this:
{
"glossary": [
{
"name": "Constant",
"pageNumber": "33",
"definition": "A value that cannot change while the program is running.",
},
{
"name": "Debugging",
"pageNumber": "45",
"definition": "The process of finding and reducing the number of defects in a computer program.",
},
{
"name": "Algorithm",
"pageNumber": "4",
"definition": "A strictly defined finite sequence of well-defined statements that provides the solution to a problem."
}
]
}
I have another file, glossaryPage.tsx where I would like to display each glossary item within a tab. I am not sure how to access the json file in order to use it within the tsx file. I ended up changing the json file to a .ts file and exported it as so:
export const glossaryItems =
[
{
"glossary": [
{
"name": "Constant",
"pageNumber": "33",
"definition": "A value that cannot change while the program is running.",
},
{
"name": "Debugging",
"pageNumber": "45",
"definition": "The process of finding and reducing the number of defects in a computer program.",
},
{
"name": "Algorithm",
"pageNumber": "4",
"definition": "A strictly defined finite sequence of well-defined statements that provides the solution to a problem."
}
]
}
]
And then imported it inside glossaryPage.tsx. I want to be able to get the each part of the json separately to be able to use it inside the tabs. So I would have one tab labeled "Constant", a second tab, "Debugging", a third tab "Algorithm" and under each tab display that information such as pagenumber and definition that applies to that tab. I tried mapping over just the glossary but was unable to. I had to map over the glossaryItems.
const GlossaryPage = () => {
const terms = glossaryItems.map(({glossary}, key) => (
<div key={key}>
{glossary.map(({name, pageNumber, definition}, key) => (
<div key={key}>
<p>{name}</p>
</div>
))}
</div>
))
return (
<SprkTabsPanel
isDefaultActive
tabBtnChildren={terms[0]} //this is where the terms are printing out on the tab
tabBtnAnalyticsString="tab-1"
tabBtnDataId="tab-1"
>
</SprkTabsPanel>
I thought that by indexing the terms it would give me the term at that index but it gives me all of the terms. This is what it looks like:
How can I get the individual values of the object?
Any help would be greatly appreciated!
Importing JSON
In order to import a .json file, you simply need to enable support in your tsconfig.json file. Set "resolveJsonModule": true inside the compilerOptions property. Now you can import the data from the JSON file as a default import.
Docs: Resolve JSON Module
Mapping Your Object
I had a look at the documentation for the Spark Design system and it seems like you need to create a separate SprkTabsPanel component for each tab. All of the individual tab panels go inside of one SprkTabs component.
import React from "react";
import { SprkTabs, SprkTabsPanel } from "#sparkdesignsystem/spark-react";
import glossaryItems from "./glossaryItems.json";
const GlossaryPage = () => {
return (
<SprkTabs idString="glossary-tabs">
{glossaryItems.glossary.map(({ name, pageNumber, definition }, key) => (
<SprkTabsPanel tabBtnChildren={name} key={key}>
<p>{definition}</p>
<p>Page Number: {pageNumber}</p>
</SprkTabsPanel>
))}
</SprkTabs>
);
};
export default GlossaryPage;

How To Render Non-Stable Parent Attribute In React

I am having issue to render a A variable Parent Attribute in React. For example
[
{
"IT2183": {
"Location": "US",
"Price": "$10",
"Name": "Chairs",
}
},
{
"IT5846": { // This Attribute is not Stable. It is Item ID which is different for every record.
"Location": "US",
"Price": "$20",
"Name": "Note Book",
}
}
]
{data.map((Item) => (
<div>
{attribute.Location} //As Attribute name in the Array is not stable. How to call it.
{attribute.Price}
{attribute.Name}
</div>
))}
In the above example The Item Id which is a parent attribute and the other objects are nested inside it. For every record it is different which is basically the Item ID. I don't know how to call it.
Thanks.
Use Object.values.
{data.map((Item) => (
<div>
{Object.values(Item)[0].Location}
{Object.values(Item)[0].Price}
{Object.values(Item)[0].Name}
</div>
))}

wrapper.children().debug() and .html() in Enzyme/Karma return different contents

Using fetchMock I want to make sure that the React component will display news stories from an external API. These tests were passing until I updated React from 15.4.2 to 16.4.2 and Enzyme from 2.9.1 to 3.7.0.
Issue is that when I run yarn run test it tells me that Error: Method “props” is only meant to be run on a single node. 0 found instead.
Putting a debugger and running wrapper.children().debug() displays the HTML without any of the news articles from fetch. However, wrapper.html() displays all the articles, which is exactly what I want. How can I run tests so that it's testing the contents in wrapper.html() not wrapper.children().debug()?
Spec file:
import News from '../../app/javascript/react/components/DailyUpdate/News'
import fetchMock from 'fetch-mock'
describe('News fetch news', () => {
let wrapper;
let newsData;
beforeEach(() => {
newsData = {
"status": "ok",
"totalResults": 5,
"articles": [
{
"source": {
"id": null,
"name": "Androidheadlines.com"
},
"author": null,
"title": "Valve's Upcoming VR Headset Leaks In Full",
"description": null,
"url": "https://www.androidheadlines.com/2018/11/valve-upcoming-vr-headset-leak.html",
"urlToImage": null,
"publishedAt": "2018-11-12T16:51:05Z",
"content": null
},
{
"source": {
"id": null,
"name": "Appleinsider.com"
},
"author": "AppleInsider",
"title": "iPhone XR sales estimates slashed by Ming-Chi Kuo, as trade war headwinds swirl",
"description": "Ming-Chi Kuo has cut expectations for sales of the iPhone XR for the next year by 30 percent to 70 million, based on a possibility of a trade war with China, and other factors possibly weighing on sales, very similar to his erroneous predictions of iPhone X v…",
"url": "https://appleinsider.com/articles/18/11/12/iphone-xr-sales-estimates-slashed-by-ming-chi-kuo-similar-to-his-iphone-x-prognostications",
"urlToImage": "https://apple.insidercdn.com/gallery/28487-44424-28273-43866-iPhone-XR-Hero-l-xl.jpg",
"publishedAt": "2018-11-12T16:14:01Z",
"content": "Ming-Chi Kuo has cut expectations for sales of the iPhone XR for the next year by 30 percent to 70 million, based on a possibility of a trade war with China, and other factors possibly weighing on sales, very similar to his erroneous predictions of iPhone X v… [+2568 chars]"
},
{
"source": {
"id": "business-insider",
"name": "Business Insider"
},
"author": "Steven John",
"title": "The best smartphone chargers you can buy",
"description": "There are lots of ways to charge your phone now, so we've rounded up the best phone chargers, including wireless, fast, car chargers, and more.",
"url": "http://uk.businessinsider.com/best-phone-charger",
"urlToImage": "https://amp.businessinsider.com/images/5be5eb4c38150718db7fce86-960-480.jpg",
"publishedAt": "2018-11-12T15:23:00Z",
"content": "Why you'll love it: The Aukey Dual Port USB-C and USB Wall Charger works with all three common charging cables — the Lightning Cable, the Micro USB, and the USB-C. Whether you need to power up an iPhone 8 Plus, a Microsoft Surface tablet, a 12-inch MacBook, o… [+1578 chars]"
},
{
"source": {
"id": null,
"name": "Cnet.com"
},
"author": "Andrew Krok",
"title": "Jaguar's one-off F-Type rally car is the gnarliest kind of homage",
"description": "This new dirt-pounder pays respect to the XK 120, itself a rally champ.",
"url": "https://www.cnet.com/roadshow/news/jaguar-f-type-convertible-rally-car/",
"urlToImage": "https://cnet4.cbsistatic.com/img/ntGwUbgZurzemPwiRfsU190qH-I=/2018/11/12/f4310247-66ff-45b4-93e8-d6ad75b30b81/jaguar-f-type-rally-ogi.jpg",
"publishedAt": "2018-11-12T15:07:48Z",
"content": "The Jaguar F-Type exudes effortless cool, but you know what would make it even better? Jaguar knows the answer -- turning it into a rally car, of course. Jaguar on Monday unveiled the F-Type rally car. Now, these won't be going into service anywhere, as they'… [+1361 chars]"
},
{
"source": {
"id": null,
"name": "Macworld.com"
},
"author": "",
"title": "13-inch MacBook Pro SSD service program FAQ: Everything you need to know",
"description": "Apple has launched an SSD repair program for the 13-inch non-Touch Bar MacBook Pro. Here's everything you need to know.",
"url": "https://www.macworld.com/article/3320456/macs/13-inch-macbook-pro-ssd-service-program-faq.html",
"urlToImage": "https://images.idgesg.net/images/article/2018/07/13in-macbook-pro-no-touchbar-2018-100765203-large.jpg",
"publishedAt": "2018-11-12T15:07:22Z",
"content": "Despite Apple’s push to turn all Mac professionals into Touch Bar devotees, the 13-inch MacBook Pro with a traditional row of function keys has remained quite popular. If you own one, you might be able to take advantage of a new SSD service program. Here’s ev… [+2698 chars]"
},
]
}
fetchMock.get('/api/v1/news', {
status: 200,
body: newsData
});
wrapper = mount(
<News />
)
})
afterEach(fetchMock.restore)
describe('News', () => {
it('renders the news with images.', (done) => {
console.log(3,wrapper);
setTimeout(() => {
expect(wrapper.find('.news-card').length).toEqual(4);
expect(wrapper.find('.news-image').length).toEqual(4);
let images = wrapper.find('.news-image')
expect(images.at(0).props().src).toEqual(newsData.articles[1].urlToImage)
expect(images.at(1).props().src).toEqual(newsData.articles[2].urlToImage)
expect(images.at(2).props().src).toEqual(newsData.articles[3].urlToImage)
expect(images.at(3).props().src).toEqual(newsData.articles[4].urlToImage)
let titles = wrapper.find('.news-title > a')
expect(titles.at(0).props().href).toEqual(newsData.articles[1].url)
expect(titles.at(1).props().href).toEqual(newsData.articles[2].url)
expect(titles.at(2).props().href).toEqual(newsData.articles[3].url)
expect(titles.at(3).props().href).toEqual(newsData.articles[4].url)
titles = wrapper.find('.news-title')
expect(titles.at(0).text()).toEqual(newsData.articles[1].title)
expect(titles.at(1).text()).toEqual(newsData.articles[2].title)
expect(titles.at(2).text()).toEqual(newsData.articles[3].title)
expect(titles.at(3).text()).toEqual(newsData.articles[4].title)
let descriptions = wrapper.find('p.news-description')
expect(descriptions.at(0).text()).toEqual(newsData.articles[1].description)
expect(descriptions.at(1).text()).toEqual(newsData.articles[2].description)
expect(descriptions.at(2).text()).toEqual(newsData.articles[3].description)
expect(descriptions.at(3).text()).toEqual(newsData.articles[4].description)
done()
})
})
})
})
Following is returned with wrapper.children().debug().
"<div className="grid-x grid-margin-x grid-margin-y news">
<h1 className="cell small-24 news-header">
News
</h1>
</div>"
Following is returned with wrapper.html().
"<div class="grid-x grid-margin-x grid-margin-y news">
<h1 class="cell small-24 news-header">News</h1>
<div class="cell small-24 large-12 news-card ">
<div class="news-image-container">
<img class="news-image" src="https://apple.insidercdn.com/gallery/28487-44424-28273-43866-iPhone-XR-Hero-l-xl.jpg">
</div>
<h3 class="news-title">
<a href="https://appleinsider.com/articles/18/11/12/iphone-xr-sales-estimates-slashed-by-ming-chi-kuo-similar-to-his-iphone-x-prognostications">
iPhone XR sales estimates slashed by Ming-Chi Kuo, as trade war headwinds swirl
</a>
</h3>
<p class="news-description">Ming-Chi Kuo has cut expectations for sales of the iPhone XR for the next year by 30 percent to 70 million, based on a possibility of a trade war with China, and other factors possibly weighing on sales, very similar to his erroneous predictions of iPhone X v…</p>
</div>
<div class="cell small-24 large-12 news-card ">
<div class="news-image-container">
<img class="news-image" src="https://amp.businessinsider.com/images/5be5eb4c38150718db7fce86-960-480.jpg">
</div>
<h3 class="news-title">
<a href="http://uk.businessinsider.com/best-phone-charger">
The best smartphone chargers you can buy
</a>
</h3>
<p class="news-description">There are lots of ways to charge your phone now, so we've rounded up the best phone chargers, including wireless, fast, car chargers, and more.</p>
</div>
<div class="cell small-24 large-12 news-card ">
<div class="news-image-container">
<img class="news-image" src="https://cnet4.cbsistatic.com/img/ntGwUbgZurzemPwiRfsU190qH-I=/2018/11/12/f4310247-66ff-45b4-93e8-d6ad75b30b81/jaguar-f-type-rally-ogi.jpg">
</div>
<h3 class="news-title">
<a href="https://www.cnet.com/roadshow/news/jaguar-f-type-convertible-rally-car/">
Jaguar's one-off F-Type rally car is the gnarliest kind of homage
</a>
</h3>
<p class="news-description">This new dirt-pounder pays respect to the XK 120, itself a rally champ.</p>
</div>
<div class="cell small-24 large-12 news-card ">
<div class="news-image-container">
<img class="news-image" src="https://images.idgesg.net/images/article/2018/07/13in-macbook-pro-no-touchbar-2018-100765203-large.jpg">
</div>
<h3 class="news-title">
<a href="https://www.macworld.com/article/3320456/macs/13-inch-macbook-pro-ssd-service-program-faq.html">
13-inch MacBook Pro SSD service program FAQ: Everything you need to know
</a>
</h3>
<p class="news-description">
Apple has launched an SSD repair program for the 13-inch non-Touch Bar MacBook Pro. Here's everything you need to know.
</p>
</div>
</div>"
News React Component
import React, { Component } from 'react';
class News extends Component {
constructor(props) {
super(props);
this.state = {
news: []
};
this.fetchNews = this.fetchNews.bind(this)
}
fetchNews() {
let weatherURL = `/api/v1/news`;
fetch(weatherURL)
.then(response => {
if (response.ok) {
return response;
} else {
let errorMessage = `${response.status} (${response.statusText})`,
error = new Error(errorMessage);
throw(error);
}
})
.then(response => response.json())
.then(data => {
this.setState({
news: data.articles
})
})
.catch(error => console.error(`Error in fetch: ${error.message}`));
}
componentDidMount(){
this.fetchNews()
}
render(){
let newsWithImage = []
let newsWithoutImage = []
this.state.news.forEach(news => {
if(news.urlToImage){
newsWithImage.push(news)
}else{
newsWithoutImage.push(news)
}
})
let news = newsWithImage.map(news => {
return(
<div key={news.title} className="cell small-24 large-12 news-card ">
<div className="news-image-container">
<img className="news-image" src={news.urlToImage} />
</div>
<h3 className="news-title"><a href={news.url}>{news.title}</a></h3>
<p className="news-description">{news.description}</p>
</div>
)
})
return(
<div className="grid-x grid-margin-x grid-margin-y news">
<h1 className="cell small-24 news-header">News</h1>
{news}
</div>
)
}
}
export default News

Using 'ref' as array in React

I have some issues when im trying to reference inputs as arrays in React with Redux.
The code below maps one Panel per article in the array.
var articles = this.props.item.array.articles.map((article, index) => {
return <Panel key={index} header={'Article ' + index}>
<Input type='select' ref='id' label='Article' defaultValue={article.id} >
{articles}
</Input>
</Panel>
})
I'm trying to construct the refs so that they're in an array format, which does not seem to be possible at the moment. Array of references. #1899
I guess i could solve this by create some sort of ref="article["+counter+"][id]"
But that is a horrible solution, and i really don't want to go down that path.
The json array below would be my desired format for the refs:
"articles": [
{
"_joinData": {
"price": "100",
"quantity": "50"
},
"id": "05f54207-fb6f-40b5-820e-26059a803343"
},
{
"_joinData": {
"price": "200",
"quantity": "70"
},
"id": "05f54207-fb6f-40b5-820e-26059a803343"
}
]
The price & quantity index would be 2 more inputs.
Which i've decided to not include in the code example.
A nice solution to this problem would be very appreciated.
I believe you can iterate through this.refs like an array by using Object.keys.
Ex. Object.keys(this.refs).forEach(key => func(this.refs[key]))
To run func function for each reference.

Resources