MagicMirror² v2.5.0 is available! For more information about this release, check out this topic.

Dealing with 404 url error in module.


  • Module Developer

    Here is my problem. My data for images ALWAYS has a url. Example:
    eolMediaURL:"http://media.eol.org/content/2012/06/13/04/74287_orig.jpg"

    I can display these easily via img.src = EOL.eolMediaURL;

    The problem is that some of the url’s are broken. I can’t use

    if (EOL.eolMediaURL === 404)) {
        img.src = "modules/MMM-EOL/images/darwin.jpg";
    

    because the url is ALWAYS there in the data. I’ve made several attempts to set a replacement image for the broken links but I have failed miserably. I humbly defer to, and thank, anyone that can lead to a solution.

    Just to be clear, eolMediaURL: is in every object and in an object loop.

    Thank you, my friends. 🙂


  • Module Developer

    @mykle1

    I found this, seems to be what you are looking for…

    The new window.fetch API is a cleaner replacement for XMLHttpRequest that makes use of ES6 promises. There’s a nice explanation here, but it boils down to (from the article):

    fetch(url).then(function(response) {
      return response.json();
    }).then(function(data) {
      console.log(data);
    }).catch(function() {
      console.log("Booo");
    });
    

    Browser support is now good in the latest releases (works in Chrome, Firefox, Edge (v14), Safari (v10.1), Opera, Safari iOS (v10.3), Android browser, and Chrome for Android), however IE will likely not get official support. GitHub has a polyfill available which is recommended to support older browsers still largely in use (esp versions of Safari pre March 2017 and mobile browsers from the same period).

    I guess whether this is more convenient than jQuery or XMLHttpRequest or not depends on the nature of the project.

    Here’s a link to the spec https://fetch.spec.whatwg.org/


  • Module Developer

    this is an example of the XMLHttpRequest mentioned in the previous post…

    var xmlHttp = null;
    
    function GetCustomerInfo()
    {
        var CustomerNumber = document.getElementById( "TextBoxCustomerNumber" ).value;
        var Url = "GetCustomerInfoAsJson.aspx?number=" + CustomerNumber;
    
        xmlHttp = new XMLHttpRequest(); 
        xmlHttp.onreadystatechange = ProcessRequest;
        xmlHttp.open( "GET", Url, true );
        xmlHttp.send( null );
    }
    
    function ProcessRequest() 
    {
        if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) 
        {
            if ( xmlHttp.responseText == "Not found" ) 
            {
                document.getElementById( "TextBoxCustomerName"    ).value = "Not found";
                document.getElementById( "TextBoxCustomerAddress" ).value = "";
            }
            else
            {
                var info = eval ( "(" + xmlHttp.responseText + ")" );
    
                // No parsing necessary with JSON!        
                document.getElementById( "TextBoxCustomerName"    ).value = info.jsonData[ 0 ].cmname;
                document.getElementById( "TextBoxCustomerAddress" ).value = info.jsonData[ 0 ].cmaddr1;
            }                    
        }
    }
    

  • Module Developer

    and this example uses jQuery…

    < script>
    $(document).ready(function(){
        $("button").click(function(){
            $.get("demo_test.asp", function(data, status){
                alert("Data: " + data + "\nStatus: " + status);
            });
        });
    });
    < /script>
    

    you would have to download or call jquery…

    downloaded and added to your module directory…

    getScripts: function() {
        return ["jquery.min.js'];
    },
    

    to call for it…

    < script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">< /script>
    

  • Module Developer

    @justjim1220

    I appreciate you trying to help but I could have kept googling myself. I’m looking for an explanation, too, and not just a random “try this!”. Thanks



  • @mykle1 sorry, you are using some words that don’t describe well what the problem is…

    i THINK you said

    when I try to load image files (local to the MM system), I use a URL string. 
    that URL string is 'relative' to the base of my server, defined by '??????' (you didn't supply that)
    
    when a URL fails to load, I get error 404. (not found). 
    
    but how do I handle this?
    

    you would add an onerror() handler for the img object
    this will get called ONLY when there is an error

    img.onerror = funtion(event_object){
    var img_with_error = event_object.currentTarget
    img_with_error.src=??? the url of the failing image
    }

    see https://www.w3schools.com/jsref/obj_event.asp
    for more info in decoding the event object


  • Module Developer

    @sdetweil said in Dealing with 404 url error in module.:

    sorry, you are using some words that don’t describe well what the problem is…

    Yes, I’m sorry about the description but you understood my meaning, so thank you for that. 👍

    Your onerror() handler suggestion is/was exactly what I needed/wanted and works beautifully. Again, thank you. I do appreciate that you took the time to give me advice/assistance. Here is the finished, working tag:

      // picture
                var img = document.createElement("img");
                img.classList.add("photo");
                img.src = EOL.eolMediaURL;
                img.onerror = function(event_object) { //  This function replaces broken image
                var img_with_error = event_object.currentTarget //  This function replaces broken image
                img_with_error.src= "modules/MMM-EOL/images/darwin.jpg" // This is the path to the replacement image
               }
                wrapper.appendChild(img);
    

    I would be remiss if I did not thank @cowboysdude, as well, for his help on this module.



  • @mykle1 note that your onerror handler could get stuck in a loop IF the forced replacement url also fails


  • Module Developer

    @sdetweil

    That’s good to know. Thanks to you again. If you were in NYC I would buy you a beer (or many). 🙂



  • @mykle1 @sdetweil came up with a beautiful answer…I didn’t do a thing LOL