I want to use JSON to retrieve my images along with their file location. My program looks like the code below.
I've tried with {photos.Lillian.portfolioImage} and with JSON.stringify(photos.Annalise.portofolio however, none of them can display the images. I've done a console.log(); and checked if the data can be read and it does appear however, the images will not appear. I've checked the source address and it works when I add it here <img src="./img/TheGuardian/Lillian.png">.
What is my error? Do I need to reformat the object called from JSON? I've seen one can use parse and fetch however, this is used for APIs and as far as I can see, this isn't?
Here's my JSON:
{
"Lillian" : {
"type": "The Guardian",
"portfolioImage": "./img/TheGuardian/Lillian.png"
},
"Annalise" : {
"type": "TheGuardian",
"portfolioImage": "./img/TheGuardian/Annalise.png"
},
"Raven" : {
"type": "DCComics",
"portfolioImage": "./img/TheGuardian/Raven.png"
}
}
Here's my HTML:
import React, { Component } from 'react';
import logo from './logo.svg';
import photos from './images.json';
import './App.css';
class App extends Component {
render() {
console.log(JSON.stringify(photos.Annalise.portfolioImage));
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>beeccy´s portfolio.</h2>
</div>
<p className="App-intro">
This was a test to present images from my portfolio.
</p>
<img src={photos.Lillian.portfolioImage} alt="Lillian" />
<img src={photos.Raven.portfolioImage} alt="Raven" />
<img src="JSON.stringify(photos.Annalise.portfolioImage)" alt="Annalise" />
</div>
);
}
}
export default App;
Like in HTML, you want to set the src attribute of an img element the source to the image. The following example also shows how you can loop over the JSON and show all images at once.
const JSON = {
Lillian: {
type: 'The Guardian',
portfolioImage: './img/TheGuardian/Lillian.png'
},
Annalise: {
type: 'TheGuardian',
portfolioImage: './img/TheGuardian/Annalise.png'
},
Raven: { type: 'DCComics', portfolioImage: './img/TheGuardian/Raven.png' }
};
class Example extends React.Component {
render() {
return (
<div>
{Object.keys(JSON).map(key => (
<div>
{JSON[key].type}
<img src={JSON[key].portfolioImage} key={key} />
</div>
))}
</div>
);
}
}
ReactDOM.render(<Example />, document.getElementById('root'));
const obj =
{
"Lillian" : { "type": "The Guardian", "portfolioImage": "./img/TheGuardian/Lillian.png" },
"Annalise" : { "type": "TheGuardian", "portfolioImage": "./img/TheGuardian/Annalise.png" },
"Raven" : { "type": "DCComics", "portfolioImage": "./img/TheGuardian/Raven.png" }
};
let images = [];
for(let item in obj){
images.push(item.portfolioImage);
}
By doing this you can retrieve images from the object of objects into the images array
Related
Good evening,
I have the following JSON structure:
"Flow": [
{
"title": "Is your multicloud secure and scalable?",
"icon": "<FontAwesomeIcon className='my-icon' icon={faShieldCheck} />"
}
],
As you can see, it uses the React version of FontAwesome Pro. But I need to render this dynamically into a Component.
So far I've tried with different approaches. For example:
<div dangerouslySetInnerHTML={ { __html: item.icon } }></div>
Also tried this:
<div> { ReactHtmlParser(item.icon) } </div>
But no luck so far.
I would appreciate any new ideas on this matter.
Thanks in advance.
Remove the quotes in your json for icon.
In fact, just provide the name of the icon in the json and use require to import the icon while rendering FontAwesomeIcon.
Working demo
Code snippet
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
const myJson = {
Flow: [
{
title: "Is your multicloud secure and scalable?",
icon: "faHighlighter"
}
]
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<FontAwesomeIcon
className="my-icon"
icon={require("#fortawesome/free-solid-svg-icons")[myJson.Flow[0].icon]}
/>
</div>
);
}
Note - below is cleaner code but it imports all icons before hand.
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
const icons = require("#fortawesome/free-solid-svg-icons");
const myJson = {
Flow: [
{
title: "Is your multicloud secure and scalable?",
icon: "faHighlighter"
}
]
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<FontAwesomeIcon className="my-icon" icon={icons[myJson.Flow[0].icon]} />
</div>
);
}
I am trying to create a dynamic photo gallery for all the characters on my app. When I click on the gallery for that particular character, It takes me to their gallery, but no images appear. Each character should have 3 images for their gallery. While the app does not break, I do get a warning message saying the following: "Failed prop type: Invalid prop source supplied to image." Can somebody look at my code and see where I am wrong?
I created a JSON file with images for each character.
//CharacterImages.js
const CharacterImages = [
{
id: "1",
name: "Homer Simpson",
urlone:
"https://i.pinimg.com/474x/f1/36/ca/f136ca04817e60fa12f4a5680101ff8b.jpg",
urltwo:
"https://i.pinimg.com/474x/b1/da/e2/b1dae2fe6ca1620e5d1949a2dcd33a0c.jpg",
urlthree:
"https://i.pinimg.com/564x/7b/53/32/7b5332ef6a981b3c54e855495ea1c828.jpg"
},
{
id: "2",
name: "Marge Simpson",
urlone:
"https://i.pinimg.com/564x/63/e4/7d/63e47d98e66622bbff5e4578ccffeffc.jpg",
urltwo:
"https://i.pinimg.com/564x/04/48/60/044860ebcd5d6c14a1140b351cb620b1.jpg",
urlthree:
"https://i.pinimg.com/564x/6d/99/26/6d9926fa54bc3650acf9295d997fc72c.jpg"
},
{
id: "3",
name: "Bart Simpson",
urlone:
"https://i.pinimg.com/564x/fe/18/af/fe18af309234936e231fa107c6d2b4c7.jpg",
urltwo:
"https://i.pinimg.com/564x/20/59/7a/20597ab32ab0f7ec8a5484fa384e0bb4.jpg",
urlthree:
"https://i.pinimg.com/564x/20/59/7a/20597ab32ab0f7ec8a5484fa384e0bb4.jpg"
}
export default CharacterImages;
I created a separate folder so that the images can come in dynamically.
// ImageGallery.js
import React, { Component } from "react";
import { StyleSheet, Text, View } from "react-native";
import { SliderBox } from "react-native-image-slider-box";
import { withNavigation } from "react-navigation";
import CharacterImages from "../Data/CharacterImages";
class ImageGallery extends React.Component {
static navigationOptions = {
title: "Gallery",
headerStyle: {
backgroundColor: "#53b4e6"
},
headerTintColor: "#f6c945",
headerTitleStyle: "bold"
};
constructor(props) {
super(props);
this.state = {
CharacterImages
};
}
render() {
return (
<View style={styles.container}>
<SliderBox
images={this.state.CharacterImages}
sliderBoxHeight={900}
onCurrentImagePressed={index =>
console.warn(`image ${index} pressed`)
}
dotColor="yellow"
inactiveDotColor="white"
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
export default withNavigation(ImageGallery);
Finally, the user can access the each characters gallery when they are in that particular profile this way:
//CharacterProfile.js
headerRight: (
<Button
onPress={() => navigation.navigate("ImageGallery")}
title="Gallery"
color="#f6c945"
/>
)
The problem here is that you are passing a whole object of datas instead of an array of strings with urls.
Try changing images prop to:
images = {this.state.CharacterImages.urlone}
Then i would advise to create a single "image" key object with the array of strings, making your CharacterImages be:
const CharacterImages = [
{
id: "1",
name: "Homer Simpson",
images:["https://i.pinimg.com/474x/f1/36/ca/f136ca04817e60fa12f4a5680101ff8b.jpg",
"https://i.pinimg.com/474x/b1/da/e2/b1dae2fe6ca1620e5d1949a2dcd33a0c.jpg",
"https://i.pinimg.com/564x/7b/53/32/7b5332ef6a981b3c54e855495ea1c828.jpg"]
},
{
id: "2",
name: "Marge Simpson",
images:["https://i.pinimg.com/564x/63/e4/7d/63e47d98e66622bbff5e4578ccffeffc.jpg",
"https://i.pinimg.com/564x/04/48/60/044860ebcd5d6c14a1140b351cb620b1.jpg",
"https://i.pinimg.com/564x/6d/99/26/6d9926fa54bc3650acf9295d997fc72c.jpg"]
},
{
id: "3",
name: "Bart Simpson",
images:["https://i.pinimg.com/564x/fe/18/af/fe18af309234936e231fa107c6d2b4c7.jpg",
"https://i.pinimg.com/564x/20/59/7a/20597ab32ab0f7ec8a5484fa384e0bb4.jpg",
"https://i.pinimg.com/564x/20/59/7a/20597ab32ab0f7ec8a5484fa384e0bb4.jpg"]
}
]
export default CharacterImages;
EDIT
Forgot that CharacterImages is an Array of objects!!!
I updated also the constant as i didn't close the array
Here you have to decide how you want to render your images based of which condition. I'm going to show you how to put them so all images gets rendered:
constructor(props){
super(props)
mergedArray=CharacterImages.map(item=> item.images).concat.apply([], mergedArray)
this.state={
images=mergedArr
}
}
After this you can use this.state.images inside your SliderBox
I want to map of over object instead of Array, my current code works great with Array map but I am getting data undefined if I map object using state props with redux.
My JSON Format:
{
"exclusive_collection": {
"id": "0",
"image_url": "media/mobilebanner/default/ExclusiveCollection-en_new.jpg"
},
"exclusive_brands": [
{
"id": "1268",
"is_featured": "0",
"name": "Spongelle",
"image_url": "media/catalog/category/Spongelle.jpg"
},
{
"id": "756",
"is_featured": "0",
"name": "Black Up",
"image_url": "media/catalog/category/Black-Up.jpg"
},
],}
Reducer function :
export function items(state = [], action) {
switch (action.type) {
case 'ITEMS_FETCH_DATA_SUCCESS':
return action.items;
default:
return state;
}
}
Child Component:
import React, { Component } from 'react';
import Slider from "react-slick";
class ShopbyCategory extends Component {
render() {
let shopbycategoryArray = [];
let shop_by_category = this.props.items.shop_by_category
for (let key in shop_by_category) {
shopbycategoryArray.push(shop_by_category[key]);
return (
<section className="celebrityslider">
<div className="row">
<div className="widget-title"><h3>Shop By Category</h3></div>
</div>
<div className="row">
<div className="col-md-12 no-padding">
<Slider {...slidersettings}>
{this.props.items.shop_by_category.map((item) => (
<div key={item.id} className="slider-item">
<img src={item.image_url} className="img-responsive"/>
</div>
))}
</Slider>
</div>
</div>
</section>
);
}
if (this.props.hasErrored) {
return <p>Sorry! There was an error loading the items</p>;
}
if (this.props.isLoading) {
return <p>Loading…</p>;
}
return (
null
);
}
}
I am able to get the data of exclusive_brands array with the code above in my component.
But I am not sure how to get the data of exclusive_collection I am always getting undefined if I am doing the below :
let exclusive_collection = this.props.items.exclusive_collection
console.log (exclusive_collection);
I would appreciate if someone can help me to map this with redux or in other way. Thanks
Edit: Got it working even if it feels kinda wrong this way.. Any ideas to make it possible to only use the filename and not a relative path would be appreciated. Anyway, here is how I got it working:
data.json
[
{
"slug": "bloom",
"name": "Bloom",
"image": {
"src": "../images/socks1.jpg"
}
}
]
Query:
{
allDataJson {
edges {
node {
slug
name
image {
src {
childImageSharp {
fluid {
src
}
}
}
}
}
}
}
}
I am trying to display an image of which the name is stored in data.json and the file itself is in src/images
src/data/data.json
[
{
"slug": "sock1",
"name": "sock1",
"image": "socks1.jpg"
}
]
If instead of the pure filename, I provide a url to any image on the web it works.. Tried getting it to work as follows:
gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/src/data`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-transformer-json`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
],
}
product.js
import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'
import get from 'lodash/get'
class ProductPage extends React.Component {
render() {
const products = get(this, 'props.data.allDataJson.edges')
console.log(products)
return (
<Layout>
{products.map(({ node }) => {
return (
<div key={node.name}>
<p>{node.name}</p>
<img src={node.image} />
</div>
)
})}
</Layout>
)
}
}
export default ProductPage
export const productsQuery = graphql`
query {
allDataJson {
edges {
node {
slug
name
image
}
}
}
}
`
All that's being outputted on the frontend is
<img src="socks1.jpg">
If I query for all files in the GraphiQl I get them, but (not sure about this one) I think the image field is just not recognized as file type field (cant query for src etc)
Any pointers would be much appreciated! :)
Your query should similar to this:
export const productsQuery = graphql`
query {
allDataJson {
edges {
node {
slug
name
image{
publicURL
childImageSharp{
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
`
Then you can output the path like this:
<img src={node.image.childImageSharp.fluid.src} />
You don't have to use fluid, you use other types of responsive images
I have a little bug in my app and can't fix it.
I need to render images from JSON.
First of all, I have a number of albums:
AlbumLayout
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link, browserHistory } from 'react-router';
class AlbumLayout extends Component {
handleClick(album){
browserHistory.push({
pathname: "album/" + album.id,
state: {albumDetails: album}
});
}
renderList(){
return this.props.albums.map((album) => {
return(
<li onClick={this.handleClick.bind(this, album)} key={album.id}>
<img alt="job" src={album.img} />
<p className="album_titulo">{album.title}</p>
</li>
);
});
}
render(){
return (
<div>
<div className="albums">
<div className="albums_caixa">
<div className="row">
<div className="col-xs-12">
<ul className="no_pad">
{this.renderList()}
</ul>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state){
return {
albums: state.album
};
}
export default connect(mapStateToProps)(AlbumLayout);
Every albums has own list of images:
List of images
import React, { Component } from 'react';
import { connect } from 'react-redux';
class AlbumsShow extends Component {
renderImage(mainData, imageIdx){
let jobDetails = this.props.albums.filter( t => t.id == this.props.params.id)[0];
return (
<div key={imageIdx} className='content'>
{mainData.images.map((image, etag) => {
return(
<div key={image.etag} className='content_box'>
<img key={image.etag} src={image.images.smallThumbnail} alt="book"/>
</div>
)
})}
</div>
)
}
render(){
return (
<div>
{this.props.image.map(this.renderImage)}
</div>
);
}
}
function mapStateToProps({image}) {
return {image};
}
export default connect(mapStateToProps)(AlbumsShow);
When user click on any Album, he should see list of images, which is parsing from JSON.
{
"images": {
"id": "01",
"etag": "01",
"images": {
"kind": "image",
"id": "1",
"etag": "1",
"smallThumbnail": "http://books.google.com/books/content?id=FaaQgVCaXU4C&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api"
}
}
}
As for me, I have mistake in List of images-file, but I can't find it.
I will really appreciate for any help.
Thanks!
I think you may just need to bind the this context in your .map function:
return (
<div>
{this.props.image.map(this.renderImage.bind(this))}
</div>
);
It also looks like you might need to add albums to your connect in that component.