2

I'm doing an Ajax query that pulls back a JSON array filled with ~50 urls to images. I then use a forEach on the array to produce a <div> nested with other <div>, with one of those <div> holding an <img> element in where I set the src equal to the current url in the forEach iteration.

The catch is that some of the urls are dead, and result in broken <img> elements ( you know, with the little images of a ripped file?). So what I do is, during the iterations, when I create my <img> element, I set the onerror attribute equal to "$(this).closest('.gramDiv').remove()", which attempts to delete a certain <img> parent element and all of that parent's childrens. This works, but I feel like it's kinda hacky, and not best practice. Is there more standardized way of doing this?

$(document).ready(function(){
    console.log("Ready");


        function adder(data,status){

            data.forEach((url,index)=>{
                let attrObj = {
                    src: url,
                    alt: 'photo ' + index, 
                    onerror: "$(this).closest('.targetDiv').remove()"
                };

                let img = $('<img>').attr(attrObj);

                let targetDiv = $('<div></div>').addClass('target');
                let picDiv = $('<div></div>').addClass('picDiv').append(img);

                let component = targetDiv.append(picDiv);

                $('#bodyDiv').append(component);
            })
        }  

        $.ajax({
            url:'https:/blahblahblah.json',
            dataType: 'json',
            success: adder,
            timeout: 3000,
            error: function(){ alert('error retrieving')}
        });


})
Alex
  • 8,461
  • 6
  • 37
  • 49
Mark Romano
  • 701
  • 3
  • 12
  • 25
  • 1
    You could create `img` for only successfully loading images/ – Satpal Apr 04 '17 at 06:20
  • @Satpal How could I check for that? – Mark Romano Apr 04 '17 at 06:20
  • 1
    `var img = new Image();img.src = url; img.onload = function () { //Append element }; ` – Satpal Apr 04 '17 at 06:22
  • 1
    Try this [link] (http://stackoverflow.com/questions/3915634/checking-if-a-url-is-broken-in-javascript) – SabirAmeen Apr 04 '17 at 06:22
  • @SabirAmeen this looks interesting, but is the Ajax pull in the example trying to pull back one piece of data, and checking the status? My issue is that my Ajax call pulls an entire array of urls, and some of them work while others done. Maybe I'm not understanding the code you linked, many of those keywords are new to me. – Mark Romano Apr 04 '17 at 06:40
  • 2
    @MarkRomano you can check each url from the array using the UrlExists function in the link. If the file is found it returns statusCode 200 else 404 – SabirAmeen Apr 04 '17 at 06:51
  • @SabirAmeen Ah ok I think I understand better now. I will try tomorrow and let you know thank you. – Mark Romano Apr 04 '17 at 06:54
  • @SabirAmeen this worked Sabir thanks alot I'm going to answer my own question with your reply. – Mark Romano Apr 04 '17 at 15:19

2 Answers2

2

You can try to use this code

$("<img/>")
    .on('load', function() { console.log("image loaded correctly"); })
    .on('error', function() { console.log("error loading image"); })
    .attr("src", $(originalImage).attr("src"))
;

From here

Community
  • 1
  • 1
Vasilij Altunin
  • 754
  • 1
  • 5
  • 18
1

Thanks to @SabirAmeen and this link for this answer.

Basically, within the forEach block, you want to run another ajax call on the URL of the current iteration, and retrieve it's status, which indicates whether it's working or broken. In my case, a working status is 200, and anything else I consider broken.

I've simplified my code from above, but it still illustrates the point:

$(document).ready(function(){
    console.log("Ready");


        //event.preventDefault();
        console.log("pressed");

        function adder(data,status){

            data = data.reduce(function(a,b){
                if(!a.includes(b)) a.push(b);
                return a;
            },[]);

            data.forEach((url,index)=>{             

                UrlExists(url, function(status){
                    if(status === 200){
                       // file was found
                       console.log('found:',status);
                       let img = $('<img>').attr('src',url);
                       $('body').append(img);
                    }
                    else {
                       // do nothing
                       console.log('not found:',status);
                    }
                });
            })
        }

        function UrlExists(url, cb){
            jQuery.ajax({
                url:      url,
                dataType: 'text',
                type:     'GET',
                complete:  function(xhr){
                    if(typeof cb === 'function')
                       cb.apply(this, [xhr.status]);
                }
            });
        }

        $.ajax({
            url:'https://yaddayadda.json',
            dataType: 'json',
            // success: adder,
            success: adder,
            //complete: remover,
            timeout: 3000,
            error: function(){ alert('error retrieving data fam')}
        });

})
Community
  • 1
  • 1
Mark Romano
  • 701
  • 3
  • 12
  • 25