0

Let's say I have the following, very simple javascript code:

function addPicture(name){
    var src = document.getElementById("mainConsole");
    var img = new Image();

    img.onload=function() {
        img.id=name;
        src.appendChild(img);
    }
    img.src = name;
}

function clearpicture(name){
  var elem = document.getElementById(name);
  elem.remove();
}

This seems to work fine as long as these functions aren't isolated in rapid succession. Making the user click on a link:

<a href="javascript:void(0);" onclick="clearpicture('1.jpg');">test1</a>

removes the picture as one would expect. However, if I just use this code:

addPicture("1.jpg");
clearpicture(1.jpg");

I get: TypeError: elem is null. I can solve this problem with a promise!

let p = new Promise(function(resolve, reject) {
    setTimeout(() => resolve(1), 1000); // (*)
    console.log("now");
}).then(function(result) {
    clearpicture("1.jpg");
});

Everything works normally (after the delay specified of course.) Then, I tried to make the promise wait on the addpicture subroutine instead of setTimeout:

let p = new Promise(function(resolve, reject) {
    addPicture("1.jpg","1",100,0,0);
resolve(1);
    
}).then(function(result) {
    clearpicture("1.jpg");
    console.log("picture removed");
});

I get the same null error. In my actual application, I have time for the image to load but if I try to remove a series of pictures at once:

clearpicture("1.jpg");
clearpicture("2.jpg");
clearpicture("3.jpg");

Nothing gets removed - although note there would be some delay since both of my subroutines do some processing before actually adding or removing anything.

How can I make javscript code wait on an image to be fully loaded or actually removed before it does anything else?

user1833028
  • 865
  • 1
  • 9
  • 18
  • 3
    Make your addpicture function return a Promise that is resolved by the img tag's onload event. – Jared Smith Jan 02 '22 at 20:49
  • You have to run `resolve()` inside `img.onload()` function. – Redu Jan 02 '22 at 20:56
  • Would there ever be something like an img.onunload? I think I need to to the same thing for removing an image as well. By the way, by passing `resolve` to the addpicture function, I managed to make it work for the loading case. – user1833028 Jan 02 '22 at 21:03

2 Answers2

2
function addPicture(name){
 return new Promise((resolve, reject)=>{
    var src = document.getElementById("mainConsole");
    var img = new Image();

    img.onload=function() {
        img.id=name;
        src.appendChild(img);
        img.src = name;
        return resolve(1)
    }
    
   img.onerror = function(){return reject()}
 }
}

addPicture.then(()=>clearPicture(name))

function clearpicture(name){
  var elem = document.getElementById(name);
  elem.remove();
}
knicholas
  • 520
  • 4
  • 10
0

function addPicture(name){
    var src = document.getElementById("mainConsole");
    var img = new Image();
    return new Promise(v => ( img.onload = _ => ( img.id = name
                                                , src.appendChild(img)
                                                , v(name)
                                                )
                            , img.src = name
                            ));
}

function clearPicture(name){
  var elem = document.getElementById(name);
  elem.remove();
}

function delay(value,ms){
  return new Promise(v => setTimeout(v,ms,value));
}

addPicture("https://i.ytimg.com/vi/1Ne1hqOXKKI/maxresdefault.jpg").then(name => delay(name,1000))
                                                                  .then(clearPicture);
img {
  height : 100vh;
}
<div id="mainConsole"></div>

Display for 1 sec and then remove.

Redu
  • 25,060
  • 6
  • 56
  • 76