title: Images not loading and not displaying on HTML canvas
body: <p>I am working on a website that, when loaded, it displays the compiled image from an HTML canvas element. My problem is that I can't tell when an image is loaded to draw it to the canvas or how to force an image to be loaded before I proceed to the next step. I have been looking through previous posts about the subject and have tried a lot of different solutions but nothing is working for me.</p>
  
  <p>I am using web2py so I do use some Python helpers which are run on the server side.</p>
  
  <p>When I use this: </p>
  
  <pre><code>canvas = document.getElementById('canvas');
  context = canvas.getContext('2d');
  image1 = new Image();
  image1.src = '{{=URL('static', 'images/image-wrap-border-land.png')}}'; //resolves to: '/SNotes/static/images/image-wrap-border-land.png'
  image1.onload = function() {
      context.drawImage(image1, 0, 0, canvas.width, canvas.height);
  };
  </code></pre>
  
  <p>Since the image isn't loaded, the onload function doesn't do anything and it skips over it. I have also tried putting the onload function before I set the source but the image still isn't drawn. </p>
  
  <p>I have tried: </p>
  
  <pre><code>//code from above
  if(image1.completed) {
      context.drawImage(image1, 0, 0, canvas.width, canvas.height);
  }
  </code></pre>
  
  <p>But have faced the same problem. </p>
  
  <p>I have also looked at the possibility that the image is producing an error as it is loaded. To catch this I wrote:</p>
  
  <pre><code>//code from above
  image1.onerror = function() {
      console.log('error');
  }
  </code></pre>
  
  <p>But the image source is fine, and the image isn't producing an error, it is just taking a long time to load. </p>
  
  <p>Is there a way to wait for an image to load before it is drawn to the canvas?</p>
  
  <hr>
  
  <p>Edit to add specificity: </p>
  
  <p>My HTML looks like this:</p>
  
  <pre><code>&lt;div id="profile-container" class="container-fluid"&gt;
      &lt;h1&gt;My Notes&lt;/h1&gt;
      &lt;div id="empty-orders" class="column-wrapper disable" style="padding-top: 5px; margin: 0 38%;"&gt;
          &lt;h3&gt;Create a Note and it will appear here&lt;/h3&gt;
          &lt;button class="btn btn-lg btn-outline"&gt;{{=A('GET STARTED', _href=URL('default', 'canvas_board_print'))}}&lt;/button&gt;
      &lt;/div&gt;
      &lt;div id="loading" class="column-wrapper"&gt;
          &lt;i class="fa fa-cog fa-spin fa-3x fa-fw"&gt;&lt;/i&gt;
      &lt;/div&gt;
      &lt;div id="row1" class="row"&gt;
  
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>My javascript looks like this:</p>
  
  <pre><code>function showOrders(note_orders) {
      var orders = note_orders;
      //console.log(orders);
      var row_num = 1;
      var node_num = 1;
      if(orders.length &gt; 0) {
          for (var i = 0; i != orders.length; i++) {
              orders[i].border = JSON.parse(orders[i].border);
              orders[i].image_retouching = JSON.parse(orders[i].image_retouching);
              orders[i].shipping_info = JSON.parse(orders[i].shipping_info);
              var new_node = $("&lt;div&gt;", {id: "node" + node_num, "class": "col-xs-3 node-wrapper"});
              var new_canvas = $('&lt;canvas&gt;', {id: "canvas" + node_num, style: 'display: none'});
              var new_image = $('&lt;img&gt;', {id: "note_prev" + node_num, 'class': 'img-responsive'});
              $('#row' + row_num).append(new_node);
              $('#node'+ node_num).append(new_canvas).append(new_image).append(processOrders(orders[i], node_num));
              node_num++;
              if (i != 0 &amp;&amp; (i + 1) % 4 == 0) {
                  row_num++;
                  var new_row = $("&lt;div&gt;", {id: "row" + row_num, "class": "row"});
                  $(' #profile-container ').append(new_row);
              }
          }
          $(' #loading ').addClass('disable');
      } else {
          $(' #loading ').addClass('disable');
          $(' #empty-orders ').removeClass('disable');
      }
  }
  function processOrders(curr_order, node_num) {
      var canvas = document.getElementById('canvas' + node_num);
      var context = canvas.getContext('2d');
  
      var image1 = new Image();
      image1.src = curr_order.image_url;
      canvas.width = image1.naturalWidth;
      canvas.height = image1.naturalHeight;
      if(image1.complete) {
          context.drawImage(image1, 0, 0, canvas.width, canvas.height);
          if(curr_order.border.style == 'color_wrap') {
              document.getElementById('note_prev' + node_num).style.border = "10px solid " + curr_order.border.color;
          } else if(curr_order.border.style == 'image_wrap') {
              var image_wrap = new Image();
              if(canvas.width &gt; canvas.height) {
                  image_wrap.src = '{{=URL('static', 'images/image-wrap-border-land.png')}}';
              } else {
                  image_wrap.src = '{{=URL('static', 'images/image-wrap-border-port.png')}}';
              }
              console.log(image_wrap);
              image_wrap.onload = function() {
                  context.drawImage(image_wrap, 0, 0, canvas.width, canvas.height);
              };
              image_wrap.onerror = function() {
                  console.log('errors');
              }
          }
      }
      document.getElementById('note_prev' + node_num).src = canvas.toDataURL('image/png');
      var node_div = document.createElement('div');
      //Other non-image informantion is appended to node_div
      return node_div;
  }
  </code></pre>
  
  <p>My problem is when drawing image_wrap, not image1 from my above example. Image1 from my code draws fine, but image_wrap won't appear when it is drawn to the canvas.</p>
  
  <hr>
  
  <p>I FIXED IT!!!</p>
  
  <p>I moved the creation of image_Wrap variable up with the creation of the image1 variable.</p>
  
  <pre><code>function processOrders(curr_order, node_num) {
      var canvas = document.getElementById('canvas' + node_num);
      var context = canvas.getContext('2d');
  
     var image1 = new Image();
     var image_wrap = new Image();
     image1.src = curr_order.image_url;
     canvas.width = image1.naturalWidth;
     canvas.height = image1.naturalHeight;
     if(image1.complete) {
         context.drawImage(image
  </code></pre>
  
  <p>I thought this wouldn't be a good idea because I didn't want to create extra variables even if they weren't going to get used, but I guess it fixed it. </p>