I am working on a personal react project for learning and considering to mapping data from a JavaScript object file (not JSON in this case). There are many ways to do it. This method of works for me
import product1 from "../../assets/images/products/product1.jpeg";
<img src={ product1 } alt="item_image" />
But I want to do it differently. I want retrieve data from a JavaScript object file (not JSON) using mapping. My data.js file contains data like this-
const data = [
{
id: 1,
title: "Meat",
price: €2.5,
category: "Grocery",
path: "../../assets/images/products/product1.jpeg",
},
{
id: 2,
title: "Milk",
price: €1.25,
category: "Drink",
path: "../../assets/images/products/product2.jpeg",
}
]
export function getData () {
return data;
}
and mapping data in this way
import { getData } from "./data";
function Product () {
const product = getData();
return (
<>
{
product.map((item) => (
<div>
<div>
<div>
<div>
<span> { item.title } </span>
</div>
<div>
<span> { item.price } </span>
</div>
</div>
<div>
<img src={ item.path } alt="item-img" />
</div>
<div>
<div>
<span> { item.category } </span>
</div>
</div>
</div>
</div>
))
}
</>
);
}
export default Product;
But I failed to get the image from this. After looking on internet, I tried to declare the path property using this method path: "file:///home/user/Documents/testapp/src/assets/images/products/product1.jpeg"
Unfortunately this method also failed to get the product image. I am expecting a better solution from the community. --Thanks.
Related
My image is not showing in React app. I am trying to fetch the path from JSON and pass the path using props in <img> tag.
Example JSON object with the product data:
let data = [
{
id: 1,
name: "Striped Slim Fit Shirt",
image: "./Assets/m1.jpg",
price: 1000,
category: "Men",
size: "XL",
inStock: true,
},
{
id: 2,
name: "Full Sleeves Slim Fit Shirt",
image: "./Assets/m2.jpg",
price: 2000,
category: "Men",
size: "L",
inStock: true,
},
];
export default data;
My parent component from which I am passing props.
import { Fragment } from "react";
import data from "../../DUMMY_DATA";
import ItemList from "./ItemList";
const HomePage = () => {
const availableItems = data.map((products) => (
<ItemList
key={products.id}
images={products.image}
name={products.name}
price={products.price}
category={products.category}
size={products.size}
/>
));
return (
<Fragment>
<div>{availableItems}</div>
</Fragment>
);
};
export default HomePage;
My child component. Here, console logging shows the correct path, but the <img> tag is not rendering it.
import { Fragment } from "react";
const ItemList = (props) => {
const { id, images, name, price, category, size, inStock } = props;
return (
<Fragment>
<div className="container text-center">
<div className="row row-cols-4" key={id}>
<div className="col">
<img src={images} />
</div>
<div className="col">{name}</div>
<div className="col">{size}</div>
<div className="col">{price}</div>
</div>
</div>
</Fragment>
);
};
export default ItemList;
I have just started working with react recently but I have been running into an issue with the project that I am working on where I'm trying to display a list of icons with links.
when storing the src for each icon in the list below it stops the entire page from rendering, and logs an error that it can't find the image. If I paste the scr directly into the code there is no error when loading the images, but for reusability and readability, I thought it would be best practice to map a list into HTML components instead.
import SideLinksCss from './sideLinks.module.css';
export default function SideLinks() {
const links = [
{
name: "linkedin",
url: "",
src: "../assets/linkedin-icon.png"
},
{
name: "github",
url: "",
src: "../assets/github-icon.png"
},
]
return (
<div className="side-links">
<ul>
{links.map(link =>
<li>
<a>
<img src={link.src} alt={link.name} />
</a>
</li>
)}
</ul>
</div>
);
}
if there is something dumb I'm missing id love to hear since I'm new to react, or if there is a better way to do it.
You do not need to import or require the images. Just put them in the public folder and they will be available. Then you can do:
function App() {
const links = [
{
alt: "fig1",
src: "./0001.jpg",
},
{
alt: "fig2",
src: "./0002.jpg",
},
];
return (
<div className="App">
<ul>
{links.map((link) => (
<li key={link.alt}>
<a>
<img src={link.src} alt={link.alt} />
</a>
</li>
))}
</ul>
</div>
);
}
export default App;
Because the images aren't imported at the top of the file it is required that you use require() inside the list of links and not inside the mapping function. If you change the code to
import SideLinksCss from './sideLinks.module.css';
export default function SideLinks() {
const links = [
{
name: "linkedin",
url: "",
src: require("../assets/linkedin-icon.png")
},
{
name: "github",
url: "",
src: require("../assets/github-icon.png")
},
]
return (
<div className="side-links">
<ul>
{links.map(link =>
<li key = {link.name}>
<a>
<img src={link.src} alt={link.name} />
</a>
</li>
)}
</ul>
</div>
);
}
it will correctly display the images
I have user interface which looks should look like this
and that picture above is just pure HTML.
So when I tried to create it with React, I am failing to align the tv shows with a particular TV channel overflowing horizontally as per the channel.
Picture of what I get in React
I am querying the data from json files that have the objects and the TV channel object looks like
{
"groupID": 16481,
"hasMediathek": true,
"storeUrlAndroid": null,
"storeUrlApple": null,
"liveWeb": "https://www.zdf.de/live-tv",
"liveApp": null,
"defaultOrder": 1000,
"hdp": false,
"quality": 2,
"name": "ZDFneo HD",
"isEncrypted": false,
"isHD": false,
"dvbTriplet": "dvb://0.0.0",
"id": null,
"major": true
}
this is connected to the shows through its groupID which shows up as channelID in the shows Object. Below is a sample for the shows object
{
"_id": "5b1f5c7da6cdf0cbbdb7e700",
"showID": 892149863,
"channelID": 16481,
"title": "Masters of Sex",
"subtitle": "Auf frischer Tat ertappt (Dirty Jobs)",
"serie": {
"no": "4",
"title": "Auf frischer Tat ertappt",
"seasonno": "2",
"info": "Staffel 2 | Folge 4"
}
this what I have done to query the data for channels
import stations from "../data/channels.json";
import data1 from "../data/1.json";
import data2 from "../data/2.json";
import data3 from "../data/3.json";
import data4 from "../data/4.json";
import data5 from "../data/5.json";
import data6 from "../data/6.json";
class Contents extends React.Component {
constructor(){
super();
this.trans = this.trans.bind(this);
}
station = { ...stations };
shows = { ...data1, ...data2, ...data3, ...data4, ...data5, ...data6 };
trans(){
Object.values(station.result.channels).map(value => {
console.log(value["groupID"], "odgdggddgdd");
return value["groupID"];
});
}
render() {
return (
<Fragment>
<TopNavBar />
<BottomNavBar />
<div className="row">
<section className="left-menus">
<div className="left-items">
{Object.values(station.result.channels).map(value => (
<div>
<img
src={`https://cdn.hd-plus.de/senderlogos/bright-cropped/${value["groupID"]}.png`}
alt=""
/>
</div>
))}
</div>
</section>
<section className="item-center">
{
Object.values(shows.result).map(value => (
<div className="shows">{
<div className="grid-items">
<div className="item">
<small>{value.startime}</small>
<small>value.resolution</small>
</div>
<div className="item-name">{value.title}</div>
</div>
}
</div>))}
</section>
</div>
</Fragment>
);
}
}
export default Contents;
I need some help with aligning the channels with their respective stations. I hope this is descriptive enough. Thank you
Updated Code for the tiles
<section className="item-center">
{
Object.values(station.result.channels).map(value => (
<div className="shows">{
shows.result.find(show => show['channelID'] === value['groupID']).map(item => (
<div className="grid-items">
<div className="item">
<small>{item.startime}</small>
<small>value.resolution</small>
</div>
<div className="item-name">{item.title}</div>
</div>
))}
</div>))}
</section>
error message
when I try to add Object.values() around it I get this
The correct solution for this (as found in the comments) is to use the filter() function. a find() function would only give back one object, or undefined, so you cannot use map on it.
shows.result.filter(show => show['channelID'] === value['groupID']).map(item =>
())
This will return every object where the channelID equals the groupID, which you can then map to a ui element.
https://www.w3schools.com/jsref/jsref_filter.asp
I'm new to React and JSX and have created a component which displays a title and image which will serve all as a link. I would now like to set the title and image by iterating through JSON data (currently my JSON is accessible via a locally defined variable).
I would like to know how to dynamically create and populate the components with the appropriate data. My code currently looks like this:
<script>
var RecipeList = React.createClass({
const items = [
{
id: 2234567,
title: "Fried Chicken",
image-url: "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
ingredient: ["Chicken", "Flour", "Eggs", "Salt", "Pepper"]
},
{
id: 2234567,
title: "Grilled Chicken",
image-url: "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
ingredient: ["Chicken", "Olive oil", "Salt", "Pepper"]
}
]
getDefaultProps: function() {
return {items: []}
},
render: function() {
var listItems = this.props.items.map(function(item) {
return(
<div className="container-fluid">
<div className="row">
<div className="recipeContainer col-sm-12 col-md-6 col-lg-4">
<h3 className="recipeTitle">{this.props.title}</h3>
<div className="recipeImage">
<img src="{this.props.image}" />
</div>
<div className="recipeBtn">See recipe</div>
</div>
</div>
</div>
);
});
return (
{listItems}
);
}
});
ReactDOM.render(
<div>
<IngredientList></IngredientList>
<RecipeList items={items}></RecipeList>
<RecipeSection></RecipeSection>
</div>
, document.getElementById("module"));
</script>
This can be achieved by passing the JSON data into the items prop of your <RecipeList /> so that this data is used to dynamically render the component via that data.
Additionally, there are a few other things to update to get this to work:
you'll want to fix the format of your input JSON so that item keys are either wrapped with quotes, or don't have hyphens.
ensure you're accessing data from the item in map() when rendering the list items, rather than accessing the item data from this
wrap the list items that you're rendering with a "root element" at the return line of your render() method. A simple solution is to usually wrap the return result with a <div>, however with more recent versions of React you can use <React.Fragment> (this allows you to return multiple elements in a render() result, without adding the extra "div element" to be resulting DOM).
Here's a working snippet:
<div id="module"></div>
<script src="https://unpkg.com/react#16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.production.min.js" crossorigin></script>
<script type="text/babel">
/*
Use class to define component using React16
*/
class RecipeList extends React.Component {
render() {
var listItems = this.props.items.map(function(item) {
return(
<div className="container-fluid">
<div className="row">
<div className="recipeContainer col-sm-12 col-md-6 col-lg-4">
<h3 className="recipeTitle">{item.title}</h3> { /* <-- Corrected this to use item.title */ }
<div className="recipeImage">
<img src={item.image} /> { /* <-- Corrected this to use item.image */ }
</div>
<div className="recipeBtn">See recipe</div>
</div>
</div>
</div>
);
});
/*
When rendering multiple DOM elements as a list, you
must wrap these with React.Fragment, or something else
like a div
*/
return (<React.Fragment>{listItems}</React.Fragment>);
}
};
/*
Declare items data array which will passed to the items
prop of the <RecipeList> component
*/
const items = [{
'id': 2234567,
'title': "Fried Chicken",
'image': "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
'ingredient': ['Chicken', 'Olive oil', 'Salt', 'Pepper']
},
{
'id': 2234567,
'title': "Grilled Chicken",
'image': "https://images.media-allrecipes.com/userphotos/560x315/4577069.jpg",
'ingredient': ['Chicken', 'Olive oil', 'Salt', 'Pepper']
}];
ReactDOM.render(
<div>
{ /* Pass the items data array to the items prop */ }
<RecipeList items={items}></RecipeList>
</div>,
document.getElementById("module"));
</script>
Hope that helps!
I need to import images(several) from my image file dynamically by a map method. First, I want to set a base URL to my images file and then read the image's name from my JSON file which includes the image property and then set the image src accordingly.
The JSON file is like below :
{
"title": "Blue Stripe Stoneware Plate",
"brand": "Kiriko",
"price": 40,
"description": "Lorem ipsum dolor sit amet...",
"image": "blue-stripe-stoneware-plate.jpg"
},
{
"title": "Hand Painted Blue Flat Dish",
"brand": "Kiriko",
"price": 28,
"description": "Lorem ipsum dolor sit amet...",
"image": "hand-painted-blue-flat-dish.jpg"
},
my images folder :
I have read the products by redux which is works perfectly =>
const products = this.props.products;
console.log(products, 'from redux');
const fetchProducts = [];
for (let key in products) {
fetchProducts.push({
...products[key]
});
}
the console.log() =>
Now I want to define a base URL like this which later use as image src by adding the image's name from the JSON file in the map method :
const baseUrl = '../../components/assets/images/';
const fetchProducts = [];
for (let key in products) {
fetchProducts.push({
...products[key]
});
}
const productCategory = fetchProducts.map((product, index) => {
return (
<Photo
key={index}
title={product.title}
brand={product.brand}
description={product.description}
imageSource={baseUrl + product.image}
imageAlt={product.title}
/>
);
});
my Photo component looks like below :
const photo = props => (
<div className={classes.Column}>
<img src={require( `${ props.imageSource }` )} alt={props.imageAlt} />
<div className={classes.Container}>
<p>{props.brand}</p>
<p>{props.title}</p>
<p>{props.price}</p>
</div>
</div>
);
export default photo;
unfortunately, I have faced this error:
Thanks in advance and sorry for my bad English :)
Import is not working like that. You can use a base URL like that:
const baseUrl = "../../components/assets/images/";
Then you can pass to your Photo component like that:
<Photo
key={index} // Don't use index as a key! Find some unique value.
title={product.title}
brand={product.brand}
description={product.description}
imageSource={baseUrl + product.image}
imageAlt={pro.title}
/>;
Lastly, in your Photo component use require:
<img src={require( `${ props.imageSource }` )} alt={props.imageAlt} />
or like that:
<img src={require( "" + props.src )} alt={props.imageAlt} />
But, don't skip "" part or don't use it directly like:
<img width="100" alt="foo" src={require( props.src )} />
since require wants an absolute path string and first two do this trick.
Try this solution for dynamic image:-
**Componet**
const photo = props => (
<div className={classes.Column}>
<img src={require( `../../components/assets/images/${props.imageSource}`)} alt={props.imageAlt} />
<div className={classes.Container}>
<p>{props.brand}</p>
<p>{props.title}</p>
<p>{props.price}</p>
</div>
</div>
);
**Include Componet**
const productCategory = fetchProducts.map((product, index) => {
return (
<Photo
key={index}
title={product.title}
brand={product.brand}
description={product.description}
imageSource={product.image}
imageAlt={product.title}
/>
);
});
So here is what I found and it worked for me.
"file-loader": "4.3.0"
React: 16.12
Run this in your terminal:
npm run eject
Check file-loader in config/webpack.config and located file-loader configurations. What I did was, I created a directory called static/media/{your_image_name.ext} following the notation there:
options: {
name: "static/media/[name].[hash:8].[ext]"
}
and then imported this image like
import InstanceName from "static/media/my_logo.png";
Happy Hacking!
After trying all kinds of solutions, including backticks <img src={require( `${ props.imageSource }` )} and others, nothing was working. I kept getting the error Cannot find module, even though my relative paths were all correct. The only primitive solution I found, if you have a relatively small number of possible images, is to predefine a Map that will map to the actual imports. (Of course this won't work for lots of images.)
import laptopHouse from '../../images/icons/laptop-house.svg'
import contractSearch from '../../images/icons/file-contract-search.svg'
..
const [iconMap, setIconMap] = useState({
'laptopHouse': laptopHouse,
'contractSearch': contractSearch,
..
});
..
<img src={iconMap[props.icon]} />
i solved this typescript issue as follows in my project.
hope this is helpful
export const countryData = {
'sl': { name: 'Sri Lanka', flag: '/flag-of-Sri-Lanka.png' },
'uk': { name: 'UK', flag: '/flag-of-United-Kingdom.png' },
'usa': { name: 'USA', flag: '/flag-of-United-States-of-America.png' },
'ca': { name: 'Canada', flag: '/flag-of-Canada.png' },
'It': { name: 'Italy', flag: '/flag-of-Italy.png' },
'aus': { name: 'Australia', flag: '/flag-of-Australia.png' },
'me': { name: 'Middle East', flag: '/flag-of-Middle-East.png' },
'other': { name: 'Other', flag: '/flag-of-World.png' }, };
"part of URL within Double quotes" + dynamic_URL_via_var combo worked for me.
<Avatar src={require('../assets'+countryData['uk']['flag'])} />
//json data.
"ProductSlider":[
{
"image":"Product1.jpg"
},
{
"image":"Product2.jpg"
}]
//mapping data list in parent component.
{sliderData.map((data) => (
<SwiperSlide className='w-10 '>
<ProductCard data={{imgSrc: data.image}} />
</SwiperSlide>
))}
//child component(linked image).
import React from 'react'
import { CardImg } from 'react-bootstrap'
export default function ProductCard(props) {
let {imgSrc} = props.data;
return (
<div className="overflow-hidden">
<div className='overflow-hidden bg-grey opacity-card' >
<CardImg
variant='top'
src={require(`../assets/images/${imgSrc}`)}
/>
</div>
<div className='text-center p-1 opacity-card-title' >
<div>Add to cart</div>
</div>
</div>
)
}
Even I got the same error
{gallery.map((ch, index) => {....
cannot find module '/../..................png'
I went wrong here, I used src instead of ch
Error
<Image src={src.image} />
Solved
<Image src={ch.image} />