1

Could you please tell me how to replace image source in react? .I am setting a src url to my img tag. If image is not present on server I want to replace src url to this one http://punemirror.indiatimes.com/photo/55813567.cms

if image is present on server then it fine .if not then I need to change source url to "http://punemirror.indiatimes.com/photo/55813567.cms "

here is my code https://codesandbox.io/s/KOrGKp3B8

I try like that

imageExists(url, callback) {
        var img = new Image();
        img.onload = function () {
            callback(true);
        };
        img.onerror = function () {
            callback(false);
        };
        img.src = url;
    }


    renderList() {
        const lis = this.items.map((item, key) => {
            var src = "http://mumbaimirror.indiatimes.com/photo/" + item.id + ".cms";
            const alt = "http://punemirror.indiatimes.com/photo/55813567.cms";

            return (
                <li key={key}>
                    <a><img src={src}/><span>{item.hl}</span></a>
                </li>
            )
        })
        return (
            <ul>
                {lis}
            </ul>
        )
    }

    render() {
        return (
            <div className="list">
                {this.renderList()}
            </div>
        )
    }
}
naveen
  • 867
  • 4
  • 18
  • 42
  • Possible duplicate of https://stackoverflow.com/questions/3984287/how-to-show-alternate-image-if-source-image-is-not-found-onerror-working-in-ie – hjrshng Jul 28 '17 at 10:52

4 Answers4

2

Check if your image exists, use this method and then in your component class :

componentWillMount() {
  var url = "http://mumbaimirror.indiatimes.com/photo/" + item.id + ".cms";
  const alt = "http://punemirror.indiatimes.com/photo/55813567.cms";
  var src = this.imageExists(url) ? url : alt;
  this.setState({ src });
}

// added from the mentioned post
function imageExists(image_url){
    var http = new XMLHttpRequest();
    http.open('HEAD', image_url, false);
    http.send();
    return http.status != 404;
}

render() {
    var src = this.state.src;
    ...
}
Fawaz
  • 3,404
  • 3
  • 17
  • 22
  • According to post - imageExists is async - therefore you cant call it in render. – Amid Jul 28 '17 at 09:10
  • @Amid The first snippet in the accepted answer of the mentioned post is sync. – Fawaz Jul 28 '17 at 09:19
  • @Fawas how does this relates/helps to the fact that OP explicitly specified in his question that `imageExists` method is accepting callback argument? – Amid Jul 28 '17 at 09:27
  • @Amid That's exactly the point in mentioning the other post. My solution uses a sync method when as compared to OPs callback approach. – Fawaz Jul 28 '17 at 09:35
  • Thanks @Fawaz for updating the post. The only problem with this approach is that if the list of images will be more that several or internet connection is week - sync checking will freeze the UI and make application unresponsive. – Amid Jul 28 '17 at 09:51
  • Agree @Amid. While this may suffice for the question asked, but for many images it should be async and update UI on callback with setState. – Fawaz Jul 28 '17 at 10:04
0

You can use object for this.

<object data={src} type="image/png">
  <img src="http://punemirror.indiatimes.com/photo/55813567.cms" />
</object>
Eugene Tsakh
  • 2,777
  • 2
  • 14
  • 27
0

On component render, you need to check server-side for all present files, and return an array of all file ids you got on the server.

When you get that array of existing files, let's call it allFileIds, you just need to do :

<li key={key}>
                <a><img src={allFileIds.indexOf(item.id) !== -1 ? src : alt}/><span>{item.hl}</span></a>
</li>

This will check if the required id was found on the server (it checks if the item.id value exists in the array of file ids that your server returned), and if not, render the alt property instead of the src. I hope that was clear!

DrunkDevKek
  • 469
  • 4
  • 17
0

First put your image collection in state instead of field.

I assume each image in your images collection contains at least one field: url. You can check your images (this.items) for existence in componentDidMount/componentWillReceiveProps. Note that your imageExists method is async - therefore you cant use it during rendering. Based on the check you can set img.src to be either undefined/null or valid URL.

Then in render check image.url and if it is missing - use default one.

Amid
  • 21,508
  • 5
  • 57
  • 54
  • I cleared but I am trying to implement this ..if you share some code then it is benefit to me – naveen Jul 28 '17 at 09:27