0

I am not new to programming (Fortran, Python) but definitively new to javascript. I also apologize for below function having been taken from another Stack Overflow post but that is the best example I found for for helping me understand want I am trying. I am writing a Reveal.js presentation that shall show satellite pictures named "sat_picts" + ymd + hr + min + ".jpg"". The pictures are updated every quarter of an hour but it may happen that when they are called the latest one is not yet available so I want to present the one before. My readings make me understand that this is a characteristic of asynchronous behaviour of the problem and that callback functions are one way of solving the issue.

Unfortunately none of the examples or readings I found show explicitely how to retrieve the results of the callback function in my case "error" and "success". I need these results for an "if, else if" block which then writes in the HTML section the actual or the previous satellite pictures.

I would appreciate if someone could show how to resolve my issue or ev. how to better implement such a solution and or indicate me an appropriate reading.

<section> // Defines Reveal.js slide
    <h5>Satellite Picture</h5>
    <script>
    function testImage(url, callback) {
        let img = new Image();
        img.onerror = img.onabort = function() {
        // callback(url, "error");
        let resx = callback(url, "error"); // thought was way to access resx i.e. "error"
        alert(resx);                       // alert is working properly
        }
        img.onload = function() {
            callback(url, "success");
            let resy = callback(url, "success"); // thought was way to access resy i.e. "success"
            alert(resy);                         // alert is working properly
        }
        img.src = url;
    };

    function record(url, result) {
    // document.write(url, result); // ==> returns result but not in the Reveal.js HTML Section
    return result;
    };

    let imgurl = "https://server/sat_picts" + ymd + hr + min + ".jpg";
    testImage(imgurl, record);

    // If the picture can be loaded then write satellite picture to document
    if (resy === "success") document.write('<img src="https://server/sat_picts" + ymd + hr + min + ".jpg">')
    // If the the picture cannot be loaded then write satellite picture from previous hour to document
    else if (resx === "error") document.write('<img src="https://server/sat_picts" + ymd + hr + min_minus_15 + ".jpg">');
    </script>
</section>
Alioth
  • 3
  • 2
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Jared Smith Mar 31 '20 at 20:56
  • Hi Jared, thank you for your answer. I had read through what you suggest and I think that this is exactly my problem but nevertheless I am not able to do the step to resolve my issue. Please see my answer to @mcgraphix. Thank you Alioth – Alioth Apr 01 '20 at 16:26
  • Try googling "Javascript Promises" or "Javascript Promise tutorial". – Jared Smith Apr 01 '20 at 17:28

2 Answers2

0

If I understand what you are trying to do, I think this is what you want:

<section id="targetSection">

<script>
    // allow a success and error call back to be passed in as separate args
    function testImage(url, successCallback, errorCallback) {
        let img = new Image();
        img.onerror = img.onabort = function() {
           errorCallback();
        }
        img.onload = function() {
           successCallback();
        }
        img.src = url;
    };




    // If the picture can be loaded then write satellite picture to document
    function. onSuccess() {
        // write the new image to the "section"
        const img = document.createElement('img');
        img.setAttribute('src', "https://server/sat_picts" + ymd + hr + min + ".jpg");
        document.getElementById('targetSection').appendChild(img);


    }

    // If the the picture cannot be loaded then write satellite picture from previous hour to document
    function onError() { 
        // write the new image to the "section"
        const img = document.createElement('img');
        img.setAttribute('src', "https://server/sat_picts" + ymd + hr + min_minus_15 + ".jpg");
     document.getElementById('targetSection').appendChild(img);

    }

    let imgurl = "https://server/sat_picts" + ymd + hr + min + ".jpg";
    // pass the two callbacks to be called on success or error respectively.
    testImage(imgurl, onSuccess, onError);
</script>
</section>
mcgraphix
  • 2,723
  • 1
  • 11
  • 15
  • Hi mcgraphix thanks for your answer, however this does not work for me. You must see it in the context of the picture being inserted in a Reveal.js presentation i.e. into a HTML
    (see my example with the h5 header). Your solution does work as such and presents the picture but totally overwriting the HTML section, the picture is shown a blank tab. The way I understand it the result (success or error) needs to be propagated back up to the calling function "testImage" and accessed from there such as the document.write() command is within the scope of the HTML section. Thank you Alioth
    – Alioth Apr 01 '20 at 16:11
  • I updated the answer to show how you can append the new image tag into the section tag. Note that I added an id attribute to the section tag. You could use a class or data- attribute as well – mcgraphix Apr 01 '20 at 17:42
  • Hi mcgraphix, now it works exactly as I want. I added img.setAttribute('height', "800px"); for proper formattting of the picture, its perfect. I have a lot to read in front of me for fully understand the document.createElement() etc. commands but that was the hint I needed. ConsequentIy I accepted your answer. Thank you again, Alioth – Alioth Apr 02 '20 at 16:31
-1

I could be wrong about this, but it looks like the error might be the way the img tags are written in the document.write functions. The img tag needs to be closed with a '/' at the end:

<img src="https://server/sat_picts" + ymd + hr + min + ".jpg" />

The other possibility I can think of is a little gotcha in HTML, which is: when the containing element only has an image tag and no other content, then they won't show the image unless they have some dimensions (height, optionally width) associated with them, so you can check your HTML and if necessary add a CSS property to it that gives it some height (and/or width) to see if this is the issue.

e.g.

<div><img src="myImg.jpg" /></div> 

would show nothing if the containing div hasn't been given a height (it will automatically span the width of the parent element).

mikkel250
  • 61
  • 1
  • 2
  • Yes, The last lines has the glitch. But he wanna ask Why can not insert the image to the `section`. He should has more knowledge about HTML. – Riceball LEE Mar 31 '20 at 23:44
  • Hi Mikkel, thank you for your answer. I corrected the img tag, you were correct. And in my example I havent shown but the document.write() contains a height = "800px" parameter for properly formatting the picture. Please see also my answer to @mcgraphix the problem is more of a scope type and the propagation (bubbling?) back of the result to the HTML level. This is as far as I am for now. Thank you Alioth – Alioth Apr 01 '20 at 16:17