Image doesnt change although the src content changes - javascript

<img [(src)]="user.photo_url" alt="profileImage">
so i have the src coming from user object and i am changing the image and the user model is updated , but the url remains the same, although the content changes.
my Update function
this.appService.uploadProfileImage(this.user._id, this.imageFormData).then((response: any) => {
this.user = response;
});
so
the user.photo_url="somr-url" remains the same , but the image on the path changes.
But its not reflecting on the UI.
So how to reflect the changes on the img when the src is updated.
Things i tried but didnt worked.
Two way binding(as shown)
ChangeDetectorRef ( detectChange function)

try this
<img src="{{user.photo_url}}" alt="profileImage">

I just tested your code, you need to use [src] instead of [(src)].
I made a small demo in stackblitz & it works just fine!
<button (click)="changeImg()">change image source</button>
<br>
<img [src]="img" alt="profileImage">
ts code:
state : boolean;
img: string;
changeImg() {
this.state = ! this.state;
this.img = this.state ? "https://image.freepik.com/free-photo/blue-sky-with-clouds_1232-936.jpg" : "https://blogs.qub.ac.uk/queensuniversitybelfast/files/2015/05/red-sky.jpg"
}

Related

Replace class using javascript is not working in reactjs

I want to change the class of dynamic element on click function for that I tried below solutions but none of these working
handleClick=(event,headerText)=>{
document.getElementsByClassName('sk-reset-filters')[0].className = 'jjjj';
}
handleClick=(event,headerText)=>{
var reset = document.querySelectorAll('.sk-reset-filters.is-disabled')[0];
console.log(reset)
if(reset){
reset.className = 'sk-reset-filters';
console.log(reset)
}
I just want to remove the is-disabled when click. I also tried using setTimout function but doesn't work. Is there anything wrong?
When I console.log(reset) I'm getting below html.
<div class="sk-reset-filters is-disabled">
<div class="sk-reset-filters__reset">Clear all</div>
</div>
You can handle disable or show dom elements with react state in this way:
state={isDisabled:true} // set a state property
handleClick=(e)=>{
e.preventDefault
this.setState({isDisabled:false}) //change !isDisabled to false when clicked
}
render() {
{isDisabled} = this.state
let disabledMarkup = isDisabled ? <div>something</div> : null}
return (<React.Fragment>{disabledMarkup}
<button onClick={this.handleClick}></button>
</React.Fragment>)}

How to preload image in a React JS component?

I'm currently rendering a child component when a signInError occurs. The signInError is stored in the parent component and if it's not null, it renders the <SignInError/> component, as per the code below:
ParentComponent.js
// Some code...
render() {
return(
<div>
<SignInForm
doSignIn={this.doSignIn}
resetSignInError={this.resetSignInError}
signInError={this.state.signInError}
/>
{this.state.signInError && <SignInError/>}
</div>
);
}
So far, so good, here's the child component SignInError.js
import React from 'react';
import RoundImage from '../../../UI/Common/RoundImage';
import Newman from '../../../../assets/newman-min.png';
class SignInError extends React.Component {
constructor(props){
super(props);
}
componentDidMount(){
const img = new Image();
img.src = Newman;
}
render(){
return(
<div>
<div>
<RoundImage src={img.src}/> // <--- img is undefined here!!!
</div>
<div>
Hello... Newman!
</div>
</div>
);
}
}
export default SignInError;
RoundImage.js
import React from 'react';
const RoundImage = (props) => {
return (
<div>
<img src={props.src}/>
</div>
);
}
export default RoundImage;
How to preload images in React.js?
This question's answer (link above) here on Stack Over flow tells me to create the img object inside the componentDidMount() method to force the browser to load it. And so I did, as you can see from the code above. But now, when I try to pass it as a prop to my grand-child component inside my render method, I can't access the img, because it was defined inside of another method.
What's the best way around this? I just need the image to be loaded and to be displayed together with the error message. Otherwise the error message will show before the image, if your browser hasn't cached it yet. Thanks for the help.
Image download happens in the browser. Rendering to the DOM also happens in the browser.
By preloading, do you mean that you want that the component renders only when the image is ready?
If so, you could do something like this:
componentDidMount() {
const img = new Image();
img.onload = () => {
// when it finishes loading, update the component state
this.setState({ imageIsReady: true });
}
img.src = Newman; // by setting an src, you trigger browser download
}
render() {
const { imageIsReady } = this.state;
if (!imageIsReady) {
return <div>Loading image...</div>; // or just return null if you want nothing to be rendered.
} else {
return <img src={Newman} /> // along with your error message here
}
}
A bit of a different approach, but if you have the image source in advance, you can add the image source to the main html file as a link ref with preload option. The browser will preload the image (with relatively low priority) and at the time your app will load the image, it should be cached in the browser memory.
<head>
..
..
<link rel="preload" href="<your_image_source_here>" as="image">
...
</head>
In this approach, we separate the preloading process from the code. It is more relevant when you have the image source in advance (and not dynamically) and when you don't need to cache a large amount of images (will be a bit messy to add a large list of links in the html head, although possible)
you can learn more about link preloading here: Preloading content with rel="preload"
In my case I start with an initial src attribute for my images and wanted to delay changing them after the image has been loaded by the browser, so I wrote the following hook in Typescript:
import { useEffect, useState } from 'react';
export const useImageLoader = (initialSrc: string, currentSrc: string) => {
const [imageSrc, _setImageSrc] = useState(initialSrc);
useEffect(() => {
const img = new Image();
img.onload = () => {
_setImageSrc(currentSrc);
};
img.src = currentSrc;
}, [currentSrc]);
return [imageSrc];
};

React - Dynamic image rendering stutters when bundled/live

I have an issue with a component that takes a name property for use as an avatar (replaces spaces with dashes and adds file format). This then gets used as the img src dynamically.
Works absolutely fine locally, no stuttering changing the image. When I bundle and deploy to surge.sh and change routes the image stutters. I expected this as each image needs to be downloaded initially but even after the image is cached, swapping the image is jerky. Any ideas? Or is there a better way to do this?
class Athlete extends Component {
constructor (props) {
super(props);
}
render () {
let name = this.props.name;
let imgName = name.replace(/\s+/g, '-').toLowerCase();
let imgSrc = '/img/athletes/' + imgName + '.jpg';
return (
<div className="winner__inner">
<img src={imgSrc} alt={name} className="winner__avatar"/>
<h3 className="winner__name">{name}</h3>
</div>
);
}
}
export default Athlete;
Link: http://boulder.surge.sh/ (desktop only - click one of the events)
GIF: https://i.gyazo.com/4dea5302d9671b4de0fadc2334f872da.gif
Cached images: https://i.imgur.com/xQLgIWq.png
Any help would be great, thanks!

How to set iron-image src to use data-binding

I have an iron-image with a placeholder, and I'd like it to show an image when I press a button. But when I update the myImages prop, the image src doesn't update. Oddly enough the placeholder prop loadingImg works, I can update it and the placeholder changes.
For example, the HTML:
<iron-image preload fade
src$="{{myImages.test1}}"
placeholder$="[[loadingImg]]"></iron-image>
and the element prop:
myImages: {
type: Object,
value: {},
},
loadingImg: {
type: String,
value: "../../img/loading.jpg"
}
and the button just sets
myImages."test1 = "http://example.com/img1.jpg"}
Initially, src should point to undefined, as myImages is empty, so myImages.test1 should be undefined. But once I give myImages.test1 a url, the img src should update. What's going wrong here?
Changes to object properties aren't observable by default. In order to make this work, you need to use this.notifyPath()
This is why the prop loadingImg, which is just a string was causing the page to update on change, but the subproperty myImages.test1 was not.
Fixed sample code:
updateImage: function(imgSrc) {
this.myImages.test1 = imgSrc;
this.notifyPath('myImages.test1');
}

Add fallback src to image on React during server fail (S3)

I have a React + Rails app and the current S3 server issues made me realize that I don't have a proper fallback mechanism when data can't be pulled from s3. I'm trying to make it work with my locally stored images for the moment and I plan on adding it the same way to my other image tags.
My img is as follows:
errorLink() {
this.onError = null;
this.src = '/img/icons/static/credentials.svg';
}
<img alt="Icon for credentials and experience" src="/img/icons/static/credentials123.svg" onError={this.errorLink.bind(this)()}/>
the src inside the image pointing to credentials123.svg is a dummy and I've added it specifically to raise the error. But it's not updating the src of my image. How can I achieve this in react? I'd rather not show broken image links to my users next time during an Amazon outage
One of the many many solutions (since it is really based on your inner React project structure). You just keep your image url in a state somewhere as a default image. Once you get your proper image url from S3 then you will replace default one in state with a new one you got.
const DEFAULT_IMAGE = '/img/icons/static/default.svg';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
url: DEFAULT_IMAGE
};
}
render() {
return (
{/* ... some UI here ... */}
<img
alt="Icon for credentials and experience"
src={this.state.url}
/>
);
}
// ....
_someAsync = () => {
// some async logic here
// In here in 5 seconds state will be updated by replacing default url
// with new url image link
setTimeout(() => this.setState({
loaded: true,
url: '/img/icons/static/credentials.svg'
}), 5000);
};
}
One simple way to do it is
Make sure you put/set the value this.state = {image: 'image-to-load.jpeg'} in render.
<img src={this.state.image} ref={image => this.image = image} onError={() => this.image.src = '/alternate-failover.jpg'
It worked for me. Small, precise, and reliable code
Ref: https://stackoverflow.com/a/42848501/10231115

Categories