[Chartjs]-Creating multiple canvas patterns fails

1👍

You need to wait for all of the patterns to load before you can log the array. In fact, the array should be the result of awaiting all the patterns, rather than a variable in the outer scope that you populate asynchronously. See Why is my variable unaltered after I modify it inside of a function? – Asynchronous code reference

As for how to solve this, you can use Promise.all() after converting each callback into a pending promise:

const surfaceNames = ['stackoverflow.com', 'codegolf.stackexchange.com', 'superuser.com', 'codereview.stackexchange.com'];
const context = document.querySelector('#canvas1').getContext('2d');
const promises = surfaceNames.map(surfaceName =>
  new Promise((resolve, reject) => {
    const image = new Image();

    image.addEventListener('load', () => {
      resolve(context.createPattern(image, 'repeat'));
    });
    image.addEventListener('error', () => {
      reject(new Error(`${surfaceName} failed to load ${image.src}`));
    });
    image.src = `https://${surfaceName}/favicon.ico`;
  }).catch(error => {
    // populating array with null entry and logging error
    // instead of ignoring all the other pending promises
    console.log(error.message);
    return null;
  })
);

Promise.all(promises).then(surfacePatterns => {
  console.log(surfacePatterns.map(pattern => pattern.constructor.name));
});
<canvas id="canvas1"></canvas>

As you can see, each of these successfully resolves with a CanvasPattern.

0👍

When calling an async function several times in this case inside a "for", you have to wait for all the calls. If you don’t wait they you lost some async calls and you got an empty array.

If you can put a snipped I’ll try to fix that problem.

window.surfacePatterns = [];
window.c = 0;
//window.surfaceNames = ['Unknown', 'Paved', 'Unpaved', 'Concrete', 'Cobblestone', 'Metal', 'Wood', 'Ground', 'Sand', 'Grass'];
window.surfaceNames = ["https://www.worldatlas.com/r/w1200-h630-c1200x630/upload/37/99/85/northern-pygmy-owl.jpg",
  "https://www.friendsofwehr.org/wp-content/uploads/2013/06/Great-horned_Owl_RWD_at_CRC1transparent.jpg"
];

$(document).ready(() => {
  console.log('Step 1: ', window.surfacePatterns);
  for (i = 0; i < window.surfaceNames.length; i++) {
    var temp = new Image();
    temp.onload = function() {
      var my = $(".canvas1")[0].getContext('2d').createPattern(temp, 'repeat');
      console.log('Step inside async: ', my);
      window.surfacePatterns.push(my);
      window.c++;
      if (window.surfaceNames.length === c) {
        console.log('Complete async calls: ', window.surfacePatterns);
      }
    }
    //temp.src = '../img/surfaces/'+ window.surfaceNames[i] + '.jpg';
    temp.src = "https://www.friendsofwehr.org/wp-content/uploads/2013/06/Great-horned_Owl_RWD_at_CRC1transparent.jpg"

  }
  console.log('Outside For: ', window.surfacePatterns);
});

function chart() {
  console.log(window.surfacePatterns);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas class="canvas1"></canvas>
<canvas class="canvas1"></canvas>

Leave a comment