Display dynamic multiple image if only present - reactjs

My backend API have mulitple file upload. User can have choice to upload one image or multiple or none. So, image array may be length 0, 1 or more.
Scenerio:
endpoint api/v1/img/1 may have gallery img1, img2, img3
endpoint api/v1/img/2 may have gallery img1
endpoint api/v1/img/3 may have gallery null
{ gallery.img_urls?.map((img, i) => (
<div key={i}>
<img src={img} alt="gallery" />
</div>
))}
It is displaying mulitiple image. But if image isn't present it raise an error
ref3.map is not a function

if don't want anything when no image or any error to render image then you can use
{ gallery.img_urls?.map((img, i) => (
<div key={i}>
<img src={img} alt="gallery" onerror="this.onerror=null; this.remove()" />
</div>
))}
OR you can set the default image src value or also if you don't want the default image then add simply null value in src.
{ gallery.img_urls?.map((img, i) => (
<div key={i}>
<img src={img} alt="gallery" onerror="this.onerror=null; this.src='Default.jpg'" />
</div>
))}

Related

Can't show component as placeholder in react-lazyload

I'm making a netflix clone. I'm fetching and displaying data from the TMDB API. Now, I'd like to show a skeleton component while the images are being rendered. Ideally, that would look something like this:
I'm using the react-lazyload package (https://www.npmjs.com/package/react-lazyload) to lazy load the images. The problem is, it doesn't display the skeleton component as the placeholder, while the images are being rendered. This is what I'm currently getting:
The code:
return (
<div className="row">
<h2>{this.props.title}</h2>
<div className="row_posters">
{this.state.movies && this.state.movies.map(movie => (
<LazyLoad key={movie.id} className="poster_container" placeholder={<SkeletonPoster key={movie.id}/>} offset={200}>
<img
key={movie.id}
className="poster"
src={`${this.baseUrl}${movie.poster_path}`}
alt={movie.name}
/>
</LazyLoad>
))}
</div>
</div>
)
How do I get the skeleton component to be shown while the image renders?

React won't load images

I am building a react blog and my images won't load. It shows me this message in console - src\components\BlogPost\index.js
Line 21:11: Redundant alt attribute. Screen-readers already announce `img` tags as an image. You don’t need to use the words `image`, `photo,` or `picture` (or any specified custom words) in the alt prop jsx-a11y/img-redundant-alt.
My source:
const BlogPost = (props) => {
return(
<div className="blogPostContainer">
<Card>
<div className="blogHeader">
<span className="blogCategory">Featured</span>
<h1 className="postTitle">..</h1>
<span className="postedBy">..</span>
</div>
<div className="postimageContainer">
<img src={require('../../blogPostimages/memories-from.jpg')} alt="Post image" />
</div>
</Card>
</div> )
}
Please help. Thank you.
<img src="example" aria-hidden alt="Picture of me taking a photo of an image" />
add "aria-hidden "
Redundant alt attribute warning doesn't prevent image loading. It means there is a meaningless alt in your image. alt attribute is useful for accessibility and must describe the image if the download fails.
Use an accurate description for images or alt="" for backgrounds and decorations.
Loading errors probably are caused by imports errors. Check image path, name, and location.
Here an example of an image import.
import logo from '../static/logo.png';
export default function Navbar() {
return (
<img src={logo} alt='website logo' />
)
}

aligning 3 items next to each others using bootstrap react

so basically i have these photos:
i have created a postItem component which is just the structure of the image and i'm calling it from the api.js component from data using .map
the problem is, i used bootstrap grid system and used row and col-lg-4 to display each 3 on one line but its not working.
postItem.js:
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
function PostItem ({src,thumbnailUrl,onClick,title}) {
return (
<div className="container-fluid text-center">
<div className="row">
<div className="col-lg-4">
<img src={src} onClick={onClick} alt="small post"></img>
<div>{title}</div>
</div>
</div>
</div>
)}
export default PostItem;
api.js:
<div>
<div>{newPhotosLocally.map(picture =>
<PostItem
key={picture.id}
src={picture.thumbnailUrl}
thumbnailUrl={picture.thumbnailUrl}
onClick={() => showPicture(picture.url,picture.id,picture.title)}
title={picture.title}/>
)}</div>
</div>
hope you can help me guys i've been stuck on this for an entire day
you have to do something like this
<div className="col-lg-4 d-flex">
{newPhotosLocally.map(picture =>
<PostItem
key={picture.id}
src={picture.thumbnailUrl}
thumbnailUrl={picture.thumbnailUrl}
onClick={() => showPicture(picture.url, picture.id, picture.title)}
title={picture.title} />
)}
</div>
because the reason is everytime iterate loop thus it will every time create new row . this is the reason you didn't get your images not align even we added display flex property ..
now remove unnecessary code from image portion .
hope you'll get it .

React conditionally returning a mapped bootstrap element based on array length

I'm creating a project page, where I'm mapping a React Bootstrap Image Carousel for each project from an array of images. That's working fine, but the problem is, if there's only one image in the array, I'd like the "next" and "previous" arrows not to appear. So I tried conditionally returning the Carousel.Item when the array length is greater than 1, and a regular image otherwise (not inside Carousel.Item tags). But because it's still within the Carousel itself, it thinks it's another Carousel slide and the arrows appear. I suspect I have the ternary statement laid out incorrectly, but every other configuration I've tried has resulted in an "Unexpected Token" error.
<Carousel>
{imageArray.map((image, id) => {
return imageArray.length > 1 ?
<Carousel.Item key={image.id}>
<div className='project-image'>
<img src={ image} style={{width: "80%"}} alt={title.rendered}/>
</div>
</Carousel.Item>
:
<div className='project-image'>
<img src={ imgUrl} style={{width: "80%"}}alt={title.rendered}/>
</div>
})}
</Carousel>
You could move the ternary operator above the Carousel and return a carousel if your array is longer than one and a static image otherwise.
In my opinion it makes more sense in general as you are currently checking the length of the array for every item iteration. However you really only need to do it once.
Here is the updated code:
{imageArray.length > 1 ?
<Carousel>
{imageArray.map((image, id) => (
<Carousel.Item key={image.id}>
<div className='project-image'>
<img src={ image} style={{width: "80%"}} alt={title.rendered}/>
</div>
</Carousel.Item>
))}
</Carousel>
:
<div className='project-image'>
<img src={ imgUrl} style={{width: "80%"}}alt={title.rendered}/>
</div>
}
You might have to changes the styles of the .project-image div a bit to accommodate for the fact that it is no longer wrapped by a Carousel.
You might want to try storing your Carousel mapping functionality outside in a const then check the length to conditionally change it's value then inject the value {images}.
const carousel = imageArray.map((image, id) => {
<Carousel>
<Carousel.Item key={image.id}>
<div className='project-image'>
<img src={ image} style={{width: "80%"}} alt={title.rendered}/>
</div>
</Carousel.Item>
</Carousel>
}
const default = (<div className='project-image'>
<img src={ imgUrl} style={{width: "80%"}}alt={title.rendered}/>
</div>)
const images = imageArray.length > 1 ? carousel : default
return (
{images}
)

How to have backup URL show if the JSON data is undefined?

const SearchResults = ({ artists }) => (
<div className="search-results">
{artists.map(val => (
<a href="# " key={uniqid()}>
<h3>{val.name}</h3>
<img
className="box-img"
src={
val.images[0].url
? val.images[0].url
: 'https://www.w3schools.com/w3css/w3css_images.asp'
}
alt=""
/>
</a>
))}
</div>
);
I have an API call going to Spotify to get a list of Artist. When the results all have an image there is no problem but if they don't, React just returns undefined and I can't figure out how to have the placeholder image show.
You can simply have a bare png default image for this in your project, then import it and use it when no image is returned from spotify, something like:
import defaultArtistImage from './myProject/assets/images/defaultArtistImage.png';
...
const SearchResults = ({ artists }) => (
<div className="search-results">
{artists.map(val => (
<a href="# " key={uniqid()}>
<h3>{val.name}</h3>
<img
className="box-img"
src={
val.images.length !== 0
? val.images[0].url
: defaultArtistImage
}
alt=""
/>
</a>
))}
</div>
);
this is simpler than retrieving the image from an external server. Also, doing val.images[0].url can give you an error if .images it's an empty array

Resources