How do I iterate over a JSON file in react? - reactjs

I'm new to React and for the life of me cannot figure this out.
I have a JSON file (Fontawesome icons):
{
"icons": [
{
"name": "Glass",
"id": "glass",
"unicode": "f000",
"created": 1,
"filter": [
"martini",
"drink",
"bar",
"alcohol",
"liquor"
],
"categories": [
"Web Application Icons"
]
},
{
"name": "Music",
"id": "music",
"unicode": "f001",
"created": 1,
"filter": [
"note",
"sound"
],
"categories": [
"Web Application Icons"
]
},
// etc
To start with I just want to return the name of each icon.
I've been trying to follow various tutorials and have:
import React, { PureComponent } from "react";
import iconList from './services/iconList';
export default class App extends PureComponent {
render() {
const items = iconList.map(data=>{
return(
<div>
<ul>
<li>
<span>{data.name}</span>
</li>
</ul>
</div>
)
})
return items;
}
}
But I get the error: .map is not a function.
I'm not sure what I can do differently. Each tutorial I see seems to use the map function. Is there a better/different way?

Try using
const items = iconList.icons.map(data=>{
Your data is an object with an icons property in it. You can also destructure your iconList when you import:
import {icons as iconList } from './services/iconList';

Related

How to render image from data object? (React)

guys!
I have object with images.
I need to go through the object and render images from there. (I will have plenty of them).
Here is my js file:
const myJson = {
"data": [
{
"id": 1,
"name": "Landscape of Saint-Remy",
"path": "./a.jpg",
"cost": 400,
},
{
"id": 2,
"name": "Landscape of Saint-Remy",
"path": "./b.jpg",
"cost": 400,
},
{
"id": 3,
"name": "Landscape of Saint-Remy",
"path": "./c.jpg",
"cost": 400,
},
]
}
export default myJson;
I try to render it in my Home component like this:
import React from 'react';
import myJson from '../../server/myJson';
function Home() {
return (
<div>
<Hi />
{myJson.data.map(key => (
<img src={require(`${key.path}`)} key={key} />
))}
</div>
)
But got an error: Module can't be found.
If I render images like this:
<img src={key.path} key={key} />
I see 200ok, but no image because I need to import it and that is why I used require to import image and use it. But it's not working.
Please, help me!
This is not the way to import images, you need to config you webpack and add file-loader or url-loader to require images inside your javascript.
Take a look at this answer:
https://stackoverflow.com/a/37673142/5497628
Here this is how you can do it
const myJson = {
"data": [
{
"id": 1,
"name": "Landscape of Saint-Remy",
"path": require("./a.jpg"),
"cost": 400,
},
{
"id": 2,
"name": "Landscape of Saint-Remy",
"path": require("./b.jpg"),
"cost": 400,
},
{
"id": 3,
"name": "Landscape of Saint-Remy",
"path": require("./c.jpg"),
"cost": 400,
},
]
}
export default myJson;
This is how you have to prepare json data.
import React from 'react';
import myJson from '../../server/myJson';
function Home() {
return (
<div>
<Hi />
{myJson.data.map(key => (
<img src={key.path} key={key} />
))}
</div>
)
This is how you can render it.

React reading nested JSON data fails when loads or refresh

I am developing a screen to show data based on search results. Below is the JSON output.
When I click search result below component is called. In the result screen i need id, name and table1, table2 data.
Table1 and Table2 are nested outputs and these will be displayed in React Table or Data Grid (next step)
Issue: Unable to render StudyData.table1.name
Options Tried
1. UseEffect()
UseEffect() able to read StudyData.studyname but not StudyData.table1.name
Assigned to a variable
Assigned to a state
2. Render
tried using map for subdocuments
Finding: It fails only first time load and refresh. I tried to comment -> save->load -> remove the comments and save. Then works (as component is loaded). I am missing something during the first time load or refresh. Please help
[
{
"id": "DD3",
"studydate": "DDD",
"studydescription": "DD3 Description",
"studyname": "DD3",
"table1": [
{
"no": "1",
"name": "DD3 Name",
"date": "Krishna",
"description\r": "1111\r"
},
{
"no": "2",
"name": "DD3 Nam2",
"date": "Test2",
"description\r": "2222\r"
},
{
"no": "3",
"name": "DD3 Name3",
"date": "Test3",
"description\r": "3333"
}
],
"table2": [
{
"No": "2",
"Study Field1": "21",
"Study Field2": "22",
"Study Field3\r": "23"
}
],
"table3": [
{
"No": "3",
"Study Field5": "T31",
"Study Field6": "T32",
"Study Field7": "T33",
"Study Field 8\r": "T34"
}
],
"_rid": "QeNcANZFTTIKAAAAAAAAAA==",
"_self": "dbs/QeNcAA==/colls/QeNcANZFTTI=/docs/QeNcANZFTTIKAAAAAAAAAA==/",
"_etag": "\"33002e92-0000-0200-0000-5fa6fe320000\"",
"_attachments": "attachments/",
"_ts": 1604779570
}
]
COMPONENT CODE
import React, { useEffect } from "react";
import api from "./UploadStudyFilesapi";
import { DataGrid } from "#material-ui/data-grid";
export default function StudyDisplay(props) {
let myData = props.Study;
const [StudyData, setStudyData] = React.useState([]);
const [Table1Rows, setTable1Rows] = React.useState([]);
useEffect(() => {
// Update the document title using the browser API
api.getStudy(myData.studyname).then((json) => setStudyData(json));
console.log(StudyData.studyname); //works
//console.log(StudyData.table1.no) //doesn't work
let myTable = StudyData.table1;
console.log(myTable);
setTable1Rows(StudyData.table1);
console.log(Table1Rows);
}, [myData]);
return (
<div>
{StudyData.length === 0 ? (
<h1>Loading...</h1>
) : (
StudyData.map((item) => (
<div key={item.studyname}>
{item.studyname}
{/* DOESNT WORK first brose or refresh*/}
{item.table1.map((key2) => (
<div>
{console.log(key2.name)}
{key2.name}
{/* Want to pass Key2 to DataGrid or React-Table */}
{/* <DataGrid rows={key2} columns={{field1:"No"}} /> */}
</div>
))}
</div>
))
)}
</div>
);
}
Thanks for your support. I added conditional rendering based on search selection in parent component. That resolved all the issues

React react-icons-kit and get Icons dynamically

How to get Icons dynamically in React using extension React Icon kit? I try to find out the way to add a icon dynamically in a MAP-loop as I get them from array "sociallinks"
here is the part of the code
....
import { Icon } from 'react-icons-kit'
import {facebook} from 'react-icons-kit/feather/facebook';
import {instagram} from 'react-icons-kit/feather/instagram';
import {twitter} from 'react-icons-kit/feather/twitter';
....
// dynamic array from redux store
"sociallinks": [
{
"_id": 1,
"type": "facebook",
"linkname": "Facebook",
"link": "https://www.facebook.com/zzzzz/"
},
{
"_id": 2,
"type": "instagram",
"linkname": "Instagram",
"link": "https://www.instagram.com/yyy/"
},
{
"_id": 3,
"type": "twitter",
"linkname": "Twitter",
"link": "https://twitter.com/xxx"
},
{
"_id": 4,
"type": "youtube",
"linkname": "Youtube",
"link": "https://www.youtube.com/user/youtube"
}
]
// problem is here how to markup icon = {xxxxx} from map item.type? item.link and item.linkname works fine.. but not item.type :(((
<ul>
{this.props.data.socialLinks.map((item,i) => (
<li key = {i}> <a href = {item.link}><Icon size={18} icon={item.type} />{item.linkname}</a></li>
))
}
</ul>

How to - multiple polylines with different colors for each polyline- react-leaflet

I'm building a small react app with Leaflet and React for showing different metro stations for Vienna.
The problem I came to was how to edit the colors for individual metro lines in react-leaflet. Image of the map with different metro lines.
Now they are all in red, I would like to customize the colors with the colors of the circles.
The colors, name and the coordinates of each metro station are edited in the GeoJSON file.
GeoJSON file (vienna_metro_lines_byLines.geojson)
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "id": "01", "properties": { "name": "U1", "color": "red" },
"geometry": { "type": "MultiLineString", "coordinates":
[
[ 48.1423652, 16.3999045 ], [ 48.1458145, 16.3856390 ], [ 48.1537071, 16.3824464 ],
]
}
},
{ "type": "Feature", "id": "02", "properties": { "name": "U2", "color": "#9933ff" },
"geometry": { "type": "MultiLineString", "coordinates":
[
[ 48.2262470, 16.5084951 ], [ 48.2345713, 16.5044830 ], [ 48.2334553, 16.4854766 ],
]
}
Component file
//data
import geojsonDataByLines from './vienna_metro_lines_byLines.geojson';
//main component
class ViennaPoliLynes extends Component {
constructor() {
super();
this.state = {
geojsonDataByLines: geojsonDataByLines
};
}
polylineLineMaker() {
const geojsonDataByLines = this.state.geojsonDataByLines;
const testMe = geojsonDataByLines.features.map((cord) => {
return cord.geometry.coordinates;
});
return testMe;
}
polylineLineColor() {
//The color for the polylines shoud go here
const geojsonDataByLines = this.state.geojsonDataByLines;
const testMe = geojsonDataByLines.features.map((cord) => {
return cord.properties.color;
});
console.log(testMe)
return testMe;
}
render() {
return (
<Polyline positions={this.polylineLineMaker()} color={this.polylineLineColor()}>
</Polyline>
);
}
}
Ty. For your time.
It seems like you are actually creating just one polyline by merging the coordinates of all polylines together. You should try rendering multiple polylines like so:
import {Map, Polyline} from 'react-leaflet'
//data
import geojsonDataByLines from './vienna_metro_lines_byLines.geojson';
//main component
class ViennaPoliLynes extends Component {
render() {
return (
<Map>
{geojsonDataByLines.features.map((feature) => (
<Polyline
positions={feature.geometry.coordinates}
color={feature.properties.color}
/>
)}
</Map>
)
}
}

Right way to parse Redux state props - using super json objects

Following my trip with React and Redux, I'm facing a problem, simple in appearance, but hard to solve : I'm setting my Redux state with a very big JSON object. Those datas are retrieved from an async call. When I'm setting it, I created an entry in my reducer with
let initialState = {
pages: []
}
Then, I'm putting different pages, with their params and datas into this pagesarray. So far so good, the state is well updated.
BUT, my different app pages use only parts of it as you can imagine. For instance, I have a page named Gallery which might need my state to look like this :
"pages": [
{
"component":"Gallery",
"key": "gallery",
"title": "Galerie photos",
"url": "/galerie-photos",
"sections": [
{
"component": "Gallery",
"params": {
"images": [
{
"id": 1,
"src": "http://lorempicsum.com/futurama/627/300/1",
"alt": "alternate text"
},
{
"id": 2,
"src": "http://lorempicsum.com/futurama/500/400/2",
"alt": "alternate text"
},
{
"id": 3,
"src": "http://lorempicsum.com/futurama/400/320/3",
"alt": "alternate text"
},
{
"id": 4,
"src": "http://lorempicsum.com/futurama/800/500/4",
"alt": "alternate text"
},
{
"id": 5,
"src": "http://lorempicsum.com/futurama/320/300/5",
"alt": "alternate text"
},
{
"id": 6,
"src": "http://lorempicsum.com/futurama/420/360/6",
"alt": "alternate text"
}
]
}
}
]
}
]
In my GalleryContainer, I'm requesting only the images property as this is the only concern of my Gallery component. I'm able to retrieve this data with no problem. Testing with the following code returns the desired images array :
But as far as I tested this, the images are not retrieved by my Gallerycomponent : when console logging on the component side, I got undefined, and on the container side, no problem.
I tested something different : I set a galleryImages property via the reducer, and set it with the gallery images directly. This worked.
The questions are : Why doesn't it work in the first case, and do in the second ? Do I have to work only with datas that are set as state properties only ? Can't I have a "super" json set in my state to work with directly ?
Thanks to light me up on this one :)
// Component
import React from 'react'
const Gallery = ({images}) => (
<div>
{images.map((image, key) =>
<div key={key} className="image-element-class" style={card}>
<img src={image.src} alt={image.alt} style={imageStyle}/>
</div>
)}
</div>
)
const card = {
width: 'calc((100% / 3) - (15px / 1.5))',
marginBottom: '15px',
boxSizing: 'border-box'
}
const imageStyle = {
width: '100%'
}
export default Gallery
// Container
import { connect } from 'react-redux'
import Gallery from '../../components/pages/Gallery'
const getImages = state => {
return {
images: state.data.pages.filter(page => page.component === 'Gallery' &&(
page.sections.filter(section => section.component === 'Gallery' &&(
section.params.images
))
)),
}
}
const mapStateToProps = state => {
return getImages(state)
}
const GalleryContainer = connect(
mapStateToProps,
{}
)(Gallery)
export default GalleryContainer
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>

Resources