reactRookie
reactRookie

Reputation: 189

functions not defined inside another function

I'm trying to make a download button and want the images to be downloadable. However, I'm facing trouble as two of my function toBlob and save functions are being told to be undefined.

What am I doing wrong here? I'm using Vue.

 methods: {
    async downloadImage(val) {
      const blob = await toBlob(src);
      save(blob, 'image.jpg');
    },

    toBlob(src) {
      new Promise((res) => {
        const img = document.createElement("img");
        const c = document.createElement("canvas");
        const ctx = c.getContext("2d");
        img.onload = ({ target }) => {
          c.width = target.naturalWidth;
          c.height = target.naturalHeight;
          ctx.drawImage(target, 0, 0);
          c.toBlob((b) => res(b), "image/jpeg", 0.5);
        };
        img.crossOrigin = "";
        img.src = src;
      });
    
      save = (blob, name = "image.jpg") => {
       const a = document.createElement("a");
       a.href = URL.createObjectURL(blob);
       a.target = "_blank";
       a.download = name;
       a.click();
      };
   }, 
 }

Upvotes: 0

Views: 79

Answers (2)

Lawrence Cherone
Lawrence Cherone

Reputation: 46650

  • To call other methods in the Vue instance you use this.

  • And you should also be returning the Promise from toBlob

methods: {
    async downloadImage(val) {
      const blob = await this.toBlob(src);
      this.save(blob, 'image.jpg');
    },
    toBlob(src) {
      return new Promise((res) => {
        const img = document.createElement("img");
        const c = document.createElement("canvas");
        const ctx = c.getContext("2d");
        img.onload = ({
          target
        }) => {
          c.width = target.naturalWidth;
          c.height = target.naturalHeight;
          ctx.drawImage(target, 0, 0);
          c.toBlob((b) => res(b), "image/jpeg", 0.5);
        };
        img.crossOrigin = "";
        img.src = src;
      });
    }
    save(blob, name = "image.jpg") {
      const a = document.createElement("a");
      a.href = URL.createObjectURL(blob);
      a.target = "_blank";
      a.download = name;
      a.click();
    }
  }
}

Upvotes: 1

junvar
junvar

Reputation: 11604

You can't reference fields defined in an object from that object. I.e., you can't do:

let x = {
  y: 0,
  z: y + 1,
};

The simplest alternative is to define the reused (or all) fields outside the object:

let y = 0;
let x = {
  y, 
  z: y + 1
};

OR

let y = 0;
let z = y + 1;
let x = {y, z};

You also have some minor syntax errors. E.g., you can't have {x: 3;}.

For your example, this would look like:

let downloadImage = async val => {
    const blob = await toBlob(src);
    save(blob, 'image.jpg');
};

let toBlob = async src => {
    new Promise((res) => {
        const img = document.createElement("img");
        const c = document.createElement("canvas");
        const ctx = c.getContext("2d");
        img.onload = ({target}) => {
            c.width = target.naturalWidth;
            c.height = target.naturalHeight;
            ctx.drawImage(target, 0, 0);
            c.toBlob((b) => res(b), "image/jpeg", 0.5);
        };
        img.crossOrigin = "";
        img.src = src;
    })
};

let save = (blob, name = "image.jpg") => {
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.target = "_blank";
    a.download = name;
    a.click();
};

let obj = {methods: {downloadImage, toBlob, save}}

Upvotes: 1

Related Questions