I am using React.js and firebase. I am fetching an image from firebase and trying to render it in a component.
When the image URL is available, I setState the URL, but the image still does not show.
componentDidMount(){
const that = this;
firebase
.storage()
.ref("hero1.png")
.getDownloadURL()
.then(url => {
console.log(url);
that.setState({url})
})
.catch(error => {
// Handle any errors
});
}
// rendering the image
...
{ this.state.url &&
this.state.slides.map((slide, index) => {
console.log(slide.imageUrl); // url is being printed here
return (
<div
key={index}
onDragStart={this.handleOnDragStart}
className="slider-wrapper"
>
<div key={index} className="slider-content">
<img src={this.state.url} /> // when I set a hard-coded url, it works, but
//does not work in state
</div>
</div>
);
})}
...
One more thing, when I resize the browser, the image shows up immediately. Don't know why
Try this one, I removed key from the child div and updated the other key to slide.imageUrl:
{ this.state.url &&
this.state.slides.map((slide, index) => {
console.log(slide.imageUrl); // url is being printed here
return (
<div
key={slide.imageUrl}
onDragStart={this.handleOnDragStart}
className="slider-wrapper"
>
<div className="slider-content">
<img src={this.state.url} /> // when I set a hard-coded url, it works, but
//does not work in state
</div>
</div>
);
})}
I was using a library (react-alice-carousel) to render the slides of images. This was causing problem. Just switched the library to react-animated-slider, and it worked.
Thanks, everybody for helping me and for your time.
Related
I am getting an error while I am trying to use base64 images I have fetched from backend. All the backend APIs are working properly. I am getting all the base64 images as response also, but images are not appearing and I am getting this error too. Can anyone fix this? Thank you in advance. :)
useEffect hook:
useEffect(()=>{
const config={
headers:{
"Content-Type":"application/json",
Authorization:`Bearer ${localStorage.getItem("token")}`
}
}
axios.get(`/api/user/public/getalbums/${id}`,config ).then(({data})=>{
setAlbum(data);
const arr=[];
for(let i=0;i<data.length;i++){
axios.get(`/api/user/private/readimage/${data[i].fileUrl}`,config).then((res)=>{
console.log(res.data);
console.log("res");
arr.push(res.data);
// setPhotos([...photos,res.data])
})
}
console.log(arr);
setPhotos(arr);
// setPhotos([...photos,res.data])
}
)
},[])
Image:
{album.length>0 && album.map((data,ind)=>{
return(
<div key={ind}>
<div className='album-card-1' ><img className="album-card-img" src={`data:image/jpg;base64, ${photos.length>0 && photos[ind]}`} onClick={()=>{
navigate(`/artist/${id}/user/album/${data._id}`)
}}/></div>
</div>
)
}
)}
Error:
data:image/jpg;base64, false
net::ERR_INVALID_URL
Your HTML code is correct, it should be showing the correct image if the base64 is coming correctly.
Probably your error is on your logic related to the album and photos arrays.
Please add an example of the values of these arrays (The console.log that you're printing).
Also, you can add a validation that check if the base 64 is not false before rendering your JSX:
return album.length > 0 && album.map((data, ind) => {
return photos.length > 0 && photos[ind] && (
<div key={ind}>
<div className='album-card-1'>
<img className="album-card-img" src={`data:image/jpg;base64, ${photos[ind]}`} onClick={() => navigate(`/artist/${id}/user/album/${data._id}`)}/>
</div>
</div>
)
});
I used PHPmyAdmin as my localhost, Axios to do backend functions and react to display on the webpage, I created a table that stores an ID and a Blob, since blob can store image data. I used state hooks and render each of the item to be displayed on the page but when I render the page, a broken image has displayed. I tried to console.log() on that image data and it displayed as {type: 'Buffer', data: Array(50639)} on the console browser.
In short, I am trying to retrieve an image from a table in the localhost and display it on the browser
React
function ProjectCard() {
const [projectCard, setProjectCard] = useState([]);
const instance = axios.create( {
baseURL: "http://localhost:3001/api",
});
useEffect(() => {
instance.get("/getAvailableProjects").then((response) => {
setProjectCard(response.data);
});
}, []);
return (
<div className="row g-4 py-4 border-bottom">
{projectCard.map((val) => {
return (
console.log(val.PROJECT_IMAGE) {/* displayed as {type: 'Buffer', data: Array(50639)} */}
<div className="col-lg-3 col-md-6 mb-2" key={val.PROJECT_ID}>
<img id="project-img" src={val.PROJECT_IMAGE} className="img-fluid" /> {/* BROKEN IMAGE */}
</div>
);
})}
</div>
)
};
export default ProjectCard;
Server
app.get("/api/getAvailableProjects", (req, res) => {
const sqlQuery = "SELECT *, from projectdetail";
db.query(sqlQuery, (_error, result) => {
res.send(result);
});
});
Is there a way to convert this blob data into an actual image?
Checkout this JS object:
<img src={URL.createObjectURL(file) alt="fooBar" />
It should look like this.
URL.createObjectURL: https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
I passed the movieId and fetched the Movie in detail.js file.
But, I see the "GET http://image.tmdb.org/t/p/w300undefined 404 (Not Found)" error in the console.
The picture shows correctly and everything is fine.
I wanted to fix this error.
And, I really appreciate it if you advise me on a better code.
My code is:
const [movie, setMovie] = useState({});
const apiImageAddress = "http://image.tmdb.org/t/p/";
const movieId = props.match.params.id;
useEffect(() => {
window.scroll(0, 0);
axios
.get(
`https://api.themoviedb.org/3/movie/${movieId}?api_key=${API}&language=en-US`
)
.then((res) => setMovie(res.data));
}, [movieId]);
return (
<Wrap>
<section className="midContainer">
<div className="detailLeft">
<img
src={`${apiImageAddress}w300${movie.poster_path}`}
alt="movie_picture"
/>
<p className="voteAverage">{movie.vote_average}</p>
</div>
<div className="detailRight">
<h1>
{movie.original_title} ({movie.status})
</h1>
<p>Release_Date:{movie.release_date}</p>
<p>
Genres:{` `}
{movie.genres && movie.genres.map((genre) => genre.name).join(", ")}
</p>
<p>
Overview: <br />
{movie.overview}
</p>
</div>
</section>
</Wrap>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
On the initial render, movie is just an empty object so movie.poster_path doesn't exist.
Just add a conditional to your img src like:
<img
src={movie.poster_path ? `${apiImageAddress}w300${movie.poster_path}` : ''}
alt="movie_picture"
/>
This is because initially when the component renders the value of movie variable in state is {}.
Therefore when the browser makes an HTTP img request you see the error.
However once the API returns and you set the value of movie in state. Browser loads in the img successfully.
To rectify this you can add a simple check
Eg.
movie.poster_path && <img..../>
I'm trying to create an image gallery component which displays small thumbnail images and a larger image 'preview'. The preview is replaced with the currently selected thumbnail.
The component allows any number of thumbnails to be passed in as children, and then an onClick prop is added to each thumbnail using cloneElement. This is working fine and I can see the new prop in the console, but nothing happens once the image is clicked. Here's my code so far:
Parent
<Gallery>
{gallery.map((thumbnail) => {
return (
<Image fluid={thumbnail.asset.fluid} />
);
})}
</Gallery>
Child
const Gallery = (props) => {
const [thumb, setThumb] = useState({
preview: null,
});
const thumbnails = React.Children.map(props.children, (child) =>
React.cloneElement(child, {
onClick: () => {
console.log("Clicked!")
setThumb({
preview: child.asset.fluid,
});
},
})
);
return (
<section>
<div className={preview}>
<Image fluid={preview} />
</div>
<div className={thumbnails}>
{thumbnails}
</div>
</section>
);
};
export default Gallery;
I'm not sure why I'm not getting any response (even in the console) when the thumbnails are clicked.
This is my first time using React so apologies if this is a terrible method, please let me know if there's a simpler/better way.
I was able to solve this issue by wrapping the <Image> component in a <div> as recommended by Nadia Chibrikova:
Parent
<Gallery>
{gallery.map((thumbnail) => {
return (
<div>
<Image fluid={thumbnail.asset.fluid} />
</div>
);
})}
</Gallery>
I'm getting an error that map is not a function on my data.
I'm getting a response back from an api that is returning an array of objects. When I don't refresh the page I can view the results displayed just fine and even navigate to view them individually (when I click on see more). However, when I refresh the page I get the
error of "Map is not a function" on my props even though the results are displaying in the console log.
I'm lost here and can't figure out why it's doing that.
componentDidMount() {
this.props.getCanyons();
}
render() {
const { canyons } = this.props;
console.log(canyons)
return (
<section>
{canyons.map(canyon => (
<section key={canyon.canyon_id}>
<h3>{canyon.canyon_name}</h3>
<img src={canyon.canyon_pic} alt={canyon.canyon_name} />
<Link key={canyon.canyon_id} to={`/canyon/${canyon.canyon_id}`}>
<button>See More</button>
</Link>
</section>
))}
</section>
);
}
}
When the api failed or having lag time to get response, it may be undefined. This kind of checking prevent you to from such problem.
return (
{canyons && canyons.map(canyon => (
...skipped code
))}
)
Typescript provide feature of adding a ? before try to access the related Object type variable
//In typescript
{canyons?.map(canyon => (
...skipped code
))}
componentDidMount() {
this.props.getCanyons();
}
render() {
const { canyons } = this.props;
console.log(canyons)
return (
<section>
{ canyons !== '' || canyons.length > 0 ? //change here
canyons.map(canyon => (
<section key={canyon.canyon_id}>
<h3>{canyon.canyon_name}</h3>
<img src={canyon.canyon_pic} alt={canyon.canyon_name} />
<Link key={canyon.canyon_id} to={`/canyon/${canyon.canyon_id}`}>
<button>See More</button>
</Link>
</section>
))
:
null
}
</section>
);
}
}
Please follow the change. It should works for you...
Many browsers provide a live view when using console.log(). When the request not finished 'canyons' is undefined. Use
console.log(JSON.parse(JSON.stringify(obj)))
For this problem, try to set default value or check variable first