Bin a data inside an image.onload in Vue JS

0

I receive a URL of an image from a database. What I'm looking for is to get the width and height of the image to form a carousel. To do so, I instantiate an image object inside a for loop, but I can not obtain the dimensions because it is not yet loaded. To solve it I use onload, but I can not get the data inside the onload function to receive it in $ data in the Vue js component.

The dataphoto structure is correct, if it is tested outside of onload it works correctly.

dataphoto": [
{
  "id_foto": "107",
  "nombre": "Chrysanthemum.jpg",
  "ruta": "picsloaded/93/Chrysanthemum.jpg",
  "toma": "93",
  "width": 0,
  "height": 0
}

....
]




 getPictureData: function() {
  var self = this;
  var foto = [];
   for (var i = 0; i < this.dataphoto.length; i++) {

    foto = new Image();
    foto.src = "/static/api/" + this.dataphoto[i].ruta;

   foto.onload = (function(nr){

          self.dataphoto[nr]["width"] = foto.width;
          self.dataphoto[nr]["height"] = foto.height;


   })(i);
  }

},

    
asked by Santiago Rueda 03.10.2017 в 13:55
source

3 answers

1

I have managed to solve using this code ...

getPictureData: function() {
  var self = this;
  var foto = [];
   for (var i = 0; i < this.dataphoto.length; i++) {


    foto = new Image();
    foto.src = "/static/api/" + this.dataphoto[i].ruta;

   foto.onload = (function(nr){

    var photoWidth = foto.width;
    var photoHeight = foto.height;
      return function (){

        console.log(nr, foto.width, photoWidth, photoHeight)
        console.log(self.dataphoto)
          self.dataphoto[nr]["width"] = photoWidth ;
          self.dataphoto[nr]["height"] = photoHeight;
      }

   })(i);

   var loadedPhoto = foto.onload;
   loadedPhoto();
  }

},

    
answered by 03.10.2017 в 15:41
1

As simple as:

const newphotos = [];
this.dataphoto.forEach((photo) => {
  const img = new Image();
  img.onload = () => {
    const { width, height } = img;
    newphotos.push({ ...photo, width, height });
  };
  img.src = photo.url;
});
this.dataphoto = newphotos;

The new array newphotos is in case you want the DOM to update after obtaining the dimensions.

    
answered by 03.10.2017 в 16:01
-1

The problem comes from this code:

foto.onload = (function(nr) {
  self.dataphoto[nr]["width"] = foto.width;
  self.dataphoto[nr]["height"] = foto.height;
})(i);

which is equivalent to the following:

let func=function (nr) {
  self.dataphoto[nr]["width"] = foto.width;
  self.dataphoto[nr]["height"] = foto.height;
}
let callback=func(i);
foto.onload=callback;

As you see, you define a function, which you call with the parameter i and the result (which is undefined , since it does not return anything) you assign it to foto.onload .

Surely what you are trying to do is something like:

function callbackGenerator(nr) {
  return function () {
    self.dataphoto[nr]["width"] = foto.width;
    self.dataphoto[nr]["height"] = foto.height;
  }
}

foto.onload=callbackGenerator(i);
    
answered by 03.10.2017 в 15:16