4
votes

I am trying to reuse a single instance of Cloudinary's upload widget to upload and retrieve uploaded media info from multiple locations in my react app?

Can I pass different resultCallbacks to the same instance of the Cloudinary upload widget?

I am building a react app where different text blocks are associated with different images. I use the Cloudinary upload widget to process uploads then display the results next to the corresponding text block.

Currently, I am spawning a new instance of the Cloudinary widget for each text block but I realize that that's resource intensive.

Trying to fix this, I created a singleton for the upload widget where I pass in the callback function I'd like to run (I'd like to append an identifier to the upload response from Cloudinary for each text block).

The problem now is that once created, I cannot dynamically alter the callback of the singleton.

Is there a way to promisify the instance or pass dynamic resultCallback functions to the single instance?

const widget = {
  window: null,
  type: null,
};

/**
 * @class UploadWidget
 */
export default class UploadWidget {
  /**
   *
   * @param {object} options widget options
   * @param {string} options.type
   * @returns {undefined}
   */
  constructor({ cb, type }) {
    if (type !== widget.type) {
      widget.window = window.cloudinary.createUploadWidget(
        {
          cloudName: process.env.CLOUD_NAME,
          uploadPreset: process.env.UPLOAD_PRESET,
          styles: {
            palette: {
              window: '#FFFFFF',
              windowBorder: '#97AB35',
              tabIcon: '#4B9960',
              menuIcons: '#5A616A',
              textDark: '#000000',
              textLight: '#FFFFFF',
              link: '#FFCC53',
              action: '#4B9960',
              inactiveTabIcon: '#6D6D6C',
              error: '#F44235',
              inProgress: '#0078FF',
              complete: '#4B9960',
              sourceBg: '#FBFBFA',
            },
            fonts: {
              default: null,
              "'Fira Sans', sans-serif": {
                url: 'https://fonts.googleapis.com/css?family=Fira+Sans',
                active: true,
              },
            },
          },
        },
        cb
      );
      widget.type = type;
    }

    return widget.window;
  }
}

cb is a function with the following definition

function(error, result) 

Where error is either null if successful or an error message if there was a failure, while result is a JSON object detailing the triggered event.

1

1 Answers

0
votes

Why not make a callback wrapper? That way you can change the variable that stores the proper callback? As you can see here i have this.callbackHandler as the callback for the uploadwidget and a variable called trueCallback which stores the intended callback function. this.callbackHandler just passes its arguments to the real callback which is a variable that can easily be defined like so:

//Redefining true callback
let uploadWidget = new UploadWidget(//variables here);
uploadWidget.trueCallback = someNewCallbackHere;

/**
 * @class UploadWidget
 */
export default class UploadWidget {
  /**
   *
   * @param {object} options widget options
   * @param {string} options.type
   * @returns {undefined}
   */
  constructor({ cb, type }) {
    this.trueCallback = cb;
    if (type !== widget.type) {
      widget.window = window.cloudinary.createUploadWidget(
        {
          cloudName: process.env.CLOUD_NAME,
          uploadPreset: process.env.UPLOAD_PRESET,
          styles: {
            palette: {
              window: '#FFFFFF',
              windowBorder: '#97AB35',
              tabIcon: '#4B9960',
              menuIcons: '#5A616A',
              textDark: '#000000',
              textLight: '#FFFFFF',
              link: '#FFCC53',
              action: '#4B9960',
              inactiveTabIcon: '#6D6D6C',
              error: '#F44235',
              inProgress: '#0078FF',
              complete: '#4B9960',
              sourceBg: '#FBFBFA',
            },
            fonts: {
              default: null,
              "'Fira Sans', sans-serif": {
                url: 'https://fonts.googleapis.com/css?family=Fira+Sans',
                active: true,
              },
            },
          },
        },
        this.callbackHandler
      );
      widget.type = type;
    }

    return widget.window;
  }

  callbackHandler = (err, res) => {
    this.trueCallback(err, res);
  }
}