0

How can I chain arrow functions that are called from (Map) object?

The "this" context is always ignored when I'm trying to do this:

function bar() {
  console.log("bar");
  return this;
}

function vaz() {
  console.log("vaz");
  return this;
}

const configMap = new Map([
  [
    "Document",
    {
      action: () => bar(),
      process: () => vaz()
    }
  ]
  //...
]);
// Error - Cannot read properties of undefined (reading 'process')
configMap.get("Document").action().process();

I know the arrow functions don't use the this they're called with, they completely ignore it. Is that even possible or is there another solution?

daniel gi
  • 396
  • 1
  • 7
  • 19

1 Answers1

4

The this needs to refer to the map value object for chaining to work. This works very naturally if you simply change the action and process to normal functions and return this from inside them. (Not from bar or vaz, since they aren't being called with any this)

function bar() {
  console.log("bar");
}

function vaz() {
  console.log("vaz");
}

const configMap = new Map([
  [
    "Document",
    {
      action: function() { bar(); return this; },
      process: function() { vaz(); return this; },
    }
  ]
  //...
]);
configMap.get("Document").action().process();

If you must use arrow functions and want this to work, you'll have to put the document object into a variable and return it instead of this.

function bar() {
  console.log("bar");
}

function vaz() {
  console.log("vaz");
}

const documentObj = {
  action: () => { bar(); return documentObj; },
  process: () => { vaz(); return documentObj; },
};
const configMap = new Map([
  ["Document", documentObj]
  //...
]);
configMap.get("Document").action().process();

Without declaring it outside, you'd need an IIFE.

function bar() {
  console.log("bar");
}

function vaz() {
  console.log("vaz");
}


const configMap = new Map([
  [
    "Document",
    (() => {
      const documentObj = {
        action: () => { bar(); return documentObj; },
        process: () => { vaz(); return documentObj; },
      };
      return documentObj;
    })(),
  ]
  //...
]);
configMap.get("Document").action().process();

But a plain function would be easier, as in the first snippet.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320