Home > front end >  How to use disconnect() to close a Uppy JS instance – Stimulus
How to use disconnect() to close a Uppy JS instance – Stimulus

Time:07-30

When I click the "back button", my Uppy form is briefly loaded twice. How can I get Stimulus to close the previous Uppy instance when I leave the page?

Following the Uppy Docs, I'm hoping something like this (code below) but I get the error: uppy is nil or undefined on disconnect().

How can I bind uppy.close() to the original instance of Uppy?

import { Controller } from "@hotwired/stimulus"
import Uppy from "@uppy/core"

export default class extends Controller {

  connect() {
    const uppy = new Uppy()
  }

  disconnect() {
    // This causes an error
    uppy.close();
  }

}

CodePudding user response:

The problem is that you are trying to access uppy as a local variable that you have set in the connect method. However, methods to get get access to other methods' scope, which is why uppy is undefined when you try to access it in the disconnect method.

Instead, you have a few options.

Option 1 - Store the variable on the class instance

Each class instance has its own this variable, and you an easily store values on it as it is an object.

By convention, the below example uses this._uppy (with an underscore) but any name will work.

import { Controller } from "@hotwired/stimulus";
import Uppy from "@uppy/core";

export default class extends Controller {

  connect() {
    // 'store' the uppy instance against your class instance
    this._uppy = new Uppy();
  }

  disconnect() {
    // read the instance and access its close method
    this._uppy.close();
  }

}

Option 2 - Store the variable globally

Another way to think about this is that you do not want to create a new Uppy instance if there is already one created.

You can store this instance on window, although this breaks the concept of your file being an isolated module.

Another way is to store the instance in the module file itself, this may create some edge case issues for unit tests but see how you go.

import { Controller } from "@hotwired/stimulus";
import Uppy from "@uppy/core";

// declare a variable in the 'module' scope (this file).
let uppy;

export default class extends Controller {

  connect() {
    // if uppy has already been instantiated - do not create a new one
    if (uppy) return;
    // 'store' the uppy instance against your module scoped global variable
    uppy = new Uppy();
  }

  disconnect() {
    // read the instance and access its close method
    uppy && uppy.close();
    // reset the variable to null
    uppy = null;
  }

}
  • Related