0

EDIT: I'm still banging my head against my desk with this.

I'm trying to set the src for a bunch of img tags in a gallery, dynamically and with javascript. Each gallery slide has img tags which I have grouped into two categories, "before" and "after". The issue is that some pages have all 8 photos, but others have less. If an image loads successfully (*In this case let's define success as the response NOT being a 404 not found), a .loaded class is added to the img which gives it a border, but if there's a 404 not found, then a .hidden class is added, which sets display: hidden to the img.

Current problem: Despite some img tags generating the following error message in the console, "GET http://blablabla/Images/gallery/job1/before-1.jpg 404 (Not Found)", the .onerror doesn't fire, the .onload does. If I inspect the img tags (which are already on the page btw) that haven't loaded, I can see they have a filled out src attribute, although ofc an image at the provided path doesn't exist. Surely it should still be an error though?

const loadImg = function (img, url) {
    return new Promise((myResolve, myReject) => {
      img.src = url;
      img.onload = myResolve(img);
      img.onerror = myReject(img);
    });
  };

  const populateBeforeImgs = function () {
    for (let i = 0; i < beforeImgs.length; i++) {
      const img = beforeImgs[i];
      const url = `Images/gallery/job${galleryIndex}/before-${i + 1}.jpg`;
      loadImg(img, url)
        .then((value) => {
          value.classList.add("loaded");
        })
        .catch((error) => {
          error.classList.add("hidden");
        });
    }
  };

  const populateAfterImgs = function () {
    for (let i = 0; i < afterImgs.length; i++) {
      const img = afterImgs[i];
      const url = `Images/gallery/job${galleryIndex}/after-${i + 1}.jpg`;
      loadImg(img, url)
        .then((value) => {
          value.classList.add("loaded");
        })
        .catch((error) => {
          error.classList.add("hidden");
        });
    }
  };
  • What is `Response.ok` ?Where does it come from ? – Jordan Breton Sep 15 '21 at 14:08
  • It was just something I tried after reading another post that was a little but similar to my issue, but it's no relevant to my code. It's just me trying something without understanding it I'm afraid – NekiMakiHaida Sep 15 '21 at 15:02
  • Your `loadImg` functions looks very incomplete - it always just calls `myResolve(img)` immediately, never actually waiting for something. Maybe you meant `img.onload = myResolve; img.onerror = myReject;`? – Bergi Sep 15 '21 at 19:02
  • @Bergi Thanks for your suggestion! I've tried what you suggested but the img tags which don't load still get resolved instead of going to the catch. – NekiMakiHaida Sep 15 '21 at 20:58
  • @NekiMakiHaida I see you've changed your code to `img.onload = myResolve(img);`. That is not what either me or Taxel wrote. – Bergi Sep 15 '21 at 21:06
  • @Bergi I'm sorry, could you please elaborate a little more? – NekiMakiHaida Sep 15 '21 at 22:41
  • @NekiMakiHaida [`onload = myResolve` is not the same as `onload = myResolve(img)`](https://stackoverflow.com/questions/7102413/why-does-click-event-handler-fire-immediately-upon-page-load) – Bergi Sep 15 '21 at 22:46
  • @Bergi Woops! I need to brush up on that difference. Thanks for all the help guys. – NekiMakiHaida Sep 15 '21 at 22:56

1 Answers1

2

The problem is your loadImg function:

if (Response.ok) {       

Response is defined on window, but Response.ok is undefined. Undefined evaluates to false (is a falsy value)

Try this:

const loadImg = function(img, url) {
  return new Promise((resolve, reject) => {
    img.src = url;
    img.onload = () => resolve(img);
    img.onerror = () => reject(img);
  });
};

const img1 = new Image();
const img2 = new Image();

loadImg(img1, "https://www.placecage.com/c/200/300").then((img) => console.log("image 1 loaded!")).catch(() => console.warn("img 1 failed to load"));
loadImg(img2, "https://ihopethisisnotavalidurladasdasd").then((img) => console.log("image 2 loaded!")).catch(() => console.warn("img 2 failed to load"))
Taxel
  • 3,859
  • 1
  • 18
  • 40
  • Hi and thanks for your reply. I did what you suggested and now everything passes, even when "Failed to load resource: the server responded with a status of 404 (Not Found)" shows up in console. Everything just gets passed to myResolve. – NekiMakiHaida Sep 15 '21 at 14:20
  • 1
    Please check out my example. If you can't get it to work please update your question with the new code and the new problem. You should check for the error with a `catch()`, not as a second parameter to `.then()` – Taxel Sep 15 '21 at 14:24
  • Thanks for all the help. This did the job. Thank you so much! – NekiMakiHaida Sep 15 '21 at 22:57