Show a default image if src image is not found - javascript

i am making a react app if the src isn't valid i replace it with a default image now sometimes a image with a valid src doesn't load from the server cuz it's not found (404) i searched on internet and tried these:
<img onError={this.src="https://image.defaul-img.jpg"} src={!imgURL ? "https://image.defaul-img.jpg" : imgURL} className="card-img-top" alt="..." />
and
<img src={!imgURL ? "https://image.defaul-img.jpg" : imgURL} className="card-img-top" alt="https://image.defaul-img.jpg" />
but none of them work what can i do

this code works i find it on stack overflow sorry i will not post a question before properly researching again
<img onError={({ currentTarget }) => {
currentTarget.onerror = null; // prevents looping
currentTarget.src = "https://image.defaultimg.jpg";
}} src={!imgURL ? "https://image.defaultimg.jpg" : imgURL} className="card-img-top" alt="..." />

Create a ref for img element and handle fallback cases,
import { useRef } from "react";
import "./styles.css";
export default function App() {
return (
<div className="App">
<Image src="/me.png" fallback="https://source.unsplash.com/random" />
</div>
);
}
function Image({ src, fallback }) {
const ref = useRef();
function handleFallback() {
// Nullify the error event for subsequent calls
ref.current.onError = null;
ref.current.src = fallback;
}
return <img alt="My img" ref={ref} src={src} onError={handleFallback} />;
}
For vanilla.js version of the handling :How does one use the onerror attribute of an img element

Related

Dynamic loading of images in React JS

I am trying to dynamically get images from my images folder based on some information retrieved from the database. Gone through as many resources as I could but still unable to solve the problem. Here's my code:
import scimitar from "../../images/scimitar.png";
import defender from "../../images/defender.png";
import arrows from "../../images/arrows.png";
import cape from "../../images/cape.png";
import platebody from "../../images/platebody.png";
const ItemCard = ({ item }) => {
return (
<div>
<p key={item.id}>ID: {item.id}</p>
<p>Name: {item.name}</p>
<p>{item.examine}</p>
<p>
<Link to={`/items/${item.id}`}>{item.name}</Link>
</p>
<img src={require(item.name)} alt={item.examine} />
</div>
)
}
const ItemList = () => {
const [items, setItems] = useState(null);
const populateItems = async () => {
const data = await getItems();
setItems(data);
};
useEffect(() => populateItems(), []);
return (
<div>
{items &&
items.map((item, index) => (
<ItemCard item={item} key={index} />
))
}
</div>
)
}
It looks like there are a couple of issues going on. Using template literals like
<img src={`../../images/${item.name}.png`} alt={item.examine} />
won't work either. The reason why is src doesn't take in a path to picture, it looks at a url your website uses. You'll need to setup your React app to serve public images (e.g. make sure something like localhost:1337/images/schimitar.png works).
Only then can you reference it using
<img src={`/images/${item.name}.png` />
To serve static files in create-react-app check out this link. If you have another setup you'll need to use something like babel-plugin-file-loader to serve public assets.
Not sure why this worked but I placed the path of the image in a variable before passing it to the src path of the image tag.
const ItemCard = ({ item }) => {
const imageItem = `/images/${item.name}.png`;
return (
<div>
<p key={item.id}>ID: {item.id}</p>
<p>Name: {item.name}</p>
<p>{item.examine}</p>
<span>Quantity: {item.quantity}</span>
<p>
<Link to={`/items/${item.id}`}>{item.name}</Link>
</p>
<img src={imageItem} alt={item.examine} />
</div>
)
}
export default ItemCard;
<img src={item.name} alt={item.examine} />
Try the following code if you are trying to get the image from a static path.
import image1 from 'images/image1.png';
<img src={image1} alt="image1" />
If you are trying to dynamically add the image then try the following code,
const imgName = "image1.png"
return (
<div>
{ imgName && <img src={`images/${imgName}`} alt="imgName" /> }
</div>
)

ReactJS Replace Broken Image with a Different Element

Is it possible to replace a broken image with a separate element entirely in reactJS?
My current code uses the onError() function to set a broken image's src
<img src={user.avatar} onError={e => e.target.src = '/static/image.png'} />
What I'd like to do is replace it with some text instead. Something like:
<img src={user.avatar} onError={() => this.replace() } />
replace function(){
return <div class='some-class'>Image not found</div> // Would replace the image element
}
Note* The user.avatar property will always be defined, and I'm not looking to use the alt attribute
Here's how I might do it for a simple image component. We just change what we return if there was an error.
export function UserImageComponent({user}){
const [isError,setIsError] = useState(false);
if(isError){
return <div class='some-class'>Image not found</div> // Would replace the image element
}
return <img src={user.avatar} onError={() => this.setIsError(true) } />
}
You can use this strategy:
class Image extends React.Component {
constructor() {
super();
this.state = {};
this.fallback = () => {
this.setState({ failed: true });
};
}
render() {
if (this.state.failed) {
return <div classname='some-class'>Image not found</div>;
} else {
return <img src={this.props.src} onError={this.fallback} />;
}
}
}
const brokenUrl = 'url.png';
const url = 'https://picsum.photos/536/354';
const app = (
<div>
<h2>Broken image:</h2>
<Image src={brokenUrl} />
<h2>Working image:</h2>
<Image src={url} />
</div>);
ReactDOM.render(app, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Alternate image source in Javascript/React

I have an app that displays images from an API.
However some of the items don't have the required backdrop_path.
How would I display a different image if the original is not available
Here's my code
const MovieItem = ({ movie }) => {
const imagePath = 'https://image.tmdb.org/t/p/w500';
return (
<img src={`${imagePath}${movie.backdrop_path}`} alt={movie.title} />
I want the img to be {movie.poster_path} but only if {movie.backdrop_path} is null or not existent.
Or alternatively a hard coded image to display instead.
here's an answer for React, using a ref to allow the component to modify the image's source if it errors (i.e. the image specified by prop 'src' doesn't exist). In this example the fallback image is hard-coded, but could also be a prop etc.
import { useRef } from 'react';
const imageWithFallback = ({ src }) => {
const imgRef = useRef();
const onImageError = () => imgRef.current.src="/fallback-image.png";
return (
<img ref={imgRef} src={src} onError={onImageError} />
)
}
you can try use img's onerror event, it will be fired when it failed to load the resource.
You can use conditionally paths like this:
const MovieItem = ({ movie }) => {
const imagePath = 'https://image.tmdb.org/t/p/w500';
const src = ${movie.backdrop_path} === null || ${movie.backdrop_path} ===
undefined ? {movie.poster_path} : ${movie.backdrop_path}
return <img src={src} alt={movie.title} />
}
<img src={`${imagePath}${movie.backdrop_path || movie.poster_path}`} alt={movie.title} />
You can use conditional statements for images.

How to make a image clickable using document.getElementById in reactjs

I am currently using the Twitch API, where I have created a file that renders the game cover image by searching. I want the user to be able to click the game image, which will redirect them to their proper Twitch Links
Search Response
My code for the game image rendering looks like this:
render() {
const { game } = this.props
return (
<div className="GameDetails">
<img src={this.formatImageUrl(game.box_art_url)} alt="" />
<p>{game.name} </p>
<p>ID: {game.id}</p>
</div>
)
}
}
export default GameImage
I tried out:
render() {
const { game } = this.props
return (
<div className="GameDetails">
<img src={this.formatImageUrl(game.box_art_url)} alt="" onClick${"https://www.twitch.tv/directory/game/${document.getElementById("SearchName").value}"}/>
<p>{game.name} </p>
<p>ID: {game.id}</p>
</div>
)
}
}
export default GameImage
Which gives me an error.
The "SearchName" value is what the user types in the search bar for the game, therefore I want to send them to the respectable twitch pages when clicked.
Of course you will receive an error, because firstly you've misspelled $ with = and secondly, onClick prop expects a function which will handle the action after clicking the image.
Suggested approach:
handleClick = () => {
// logic when user clicks on image
// https://www.twitch.tv/directory/game/${document.getElementById("SearchName").value}
}
render() {
const { game } = this.props
return (
<div className="GameDetails">
<img src={this.formatImageUrl(game.box_art_url)} alt="" onClick={this.handleClick} />
<p>{game.name} </p>
<p>ID: {game.id}</p>
</div>
)
}
export default GameImage
Edit: It's kinda difficult to understand what you really want to achieve, however if you want that img to work as a link, you should consider using a element instead. Just wrap your img tag as well as p into a.
render() {
const { game} = this.props
const link = `https://www.twitch.tv/directory/game/${document.getElementById("SearchName").value}`;
return (
<div className="GameDetails">
<a href={link}>
<img src={this.formatImageUrl(game.box_art_url)} alt="" onClick={this.handleClick} />
<p>{game.name} </p>
<p>ID: {game.id}</p>
</a>
</div>
)
}
If all you want to do is go to another site by clicking on the image simply wrap it in an HTML anchor with the url as the href attribute. Hover over the images (don't click on them) to see the URL in the browser status bar.
function App({ data }) {
return data.map(game => <Details game={game} />);
}
function Details({ game }) {
return (
<div className="gameDetails">
<a href={game.twitch_url}>
<img src={game.box_art_url} />
</a>
</div>
);
}
const data = [
{ id: 1, twitch_url: 'http://game1.com', box_art_url: 'https://dummyimage.com/100x100/000/fff' },
{ id: 2, twitch_url: 'http://game2.com', box_art_url: 'https://dummyimage.com/100x100/555/fff' },
];
ReactDOM.render(
<App data={data} />,
document.getElementById('container')
);
.gameDetails {
display: inline-block;
padding: 0.3em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>

Passing div data from map in other component

I am creating Test component using Carousel component.
In Carousel component I am passing div with data from props.But I want to pass img src from testData props as follows.
export default class Test extends Component {
render() {
const { testData } = this.props;
return (
<div>
<Carousel>
{
testData.length && testData.map((a) => (
<div><img src=
{a.link} />
</div>
)
)
}
</Carousel>
</div>
);
}
}
testData = [{"link":"/test1.jpg"},
{"link":"/test2.jpg"},
{"link":"/test3.jpg"}
]
When I do this as follows then it is working fine.
<div> <img src="/test1.jpg" /></div>
<div> <img src="/test2.jpg" /></div>
<div> <img src="/test3.jpg" /></div>
What I am doing wrong using testData.
Regular JavaScript comments are not allowed in JSX:
//<div> <img src="/test1.jpg" /></div>
//<div> <img src="/test2.jpg" /></div>
//<div> <img src="/test3.jpg" /></div>
To comment in JSX you must wrap in { }.
{ /*<div> <img src="/test1.jpg" /></div>
<div> <img src="/test2.jpg" /></div>
<div> <img src="/test3.jpg" /></div>*/ }
import React, { Component } from 'react'
import {Carousel} from 'react-bootstrap'
export default class Test extends Component {
render() {
const testData = [{"link":"/test1.jpg"},
{"link":"/test2.jpg"},
{"link":"/test3.jpg"}]
return (
<Carousel>
{testData.length && testData.map((a) =>
(<div>
<img src={a.link} />
</div>))}
</Carousel>
);
}
}
This piece of code is working fine, So I think the problem lies in how you are passing testData through props.
If you could provide the code where you are passing the testData as props a solution can be found out.
I finally got the issue.
In first case when I am using static data as
testData = [{"link":"/test1.jpg"},
{"link":"/test2.jpg"},
{"link":"/test3.jpg"}
]
It will get showed to page every time component rendered.
But in second case
const { testData } = this.props;
testData is set by API call.So it will not get fetched when component rendered first.To resolve this issue I did this
if (!caurosalData.length) {
return null;
}
Now it is working fine

Categories