skip to Main Content

I created a very simple module that uses this:

// log.js
const logger = {

  enabled: false,

  log: (label, value) => {
    let isEnabled = false;
    console.log("BEFORE this");
    try {
      isEnabled = this.enabled;
      console.log("AFTER this");
    }
    catch(err) {
      console.log("ERR calling this ", err);
    }
    if (!isEnabled) {
      return;
    }
    console.log(label, value);
  }
};

export default logger;

I want to use this module from an asyncThunk created function:

import logger from "./log";

export const dqsLogin = createAsyncThunk(
  "user/login",
  async ({username, password}, thunkAPI) => {

    console.log("BEFORE")
    logger.log("TEST:", "test");
    console.log("AFTER")

    // more code...
  }
);

but I’m receiving an exception in the line isEnabled = this.enabled;. The error says: "TypeError: Cannot read properties of undefined (reading ‘enabled’)". The problem is "this" is undefined in the call.

If substituting "this" by "logger" like isEnabled = logger.enabled; the library works as intended. But I don’t want to make that change. Supposedly the usage of arrow functions in the object solves the any problem with "this".
What is wrong here? Cannot I use "this" in a library to be called by an asyncThunk function?

2

Answers


  1. Arrow functions don’t have the this keyword binding.
    They also don’t have access to arguments, etc.
    Use this:

    log(label, value) {
        // ...some code
    }
    

    Useful Link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

    Login or Signup to reply.
  2. The issue you are facing is related to how arrow functions handle the this context. Arrow functions do not have their own this value; instead, they inherit the this value from the surrounding lexical scope (the context in which they were created). In your case, the arrow function inside the logger object is inheriting the this value of the module, which is undefined since the module does not have a this context.

    To use this in the logger object, you would need to use a regular function declaration for the log method, not an arrow function. Here’s the updated code for the log.js module:

    // log.js
    
    const logger = {
      enabled: false,
    
      log: function(label, value) { // Use a regular function here, not an arrow function
        let isEnabled = false;
        console.log("BEFORE this");
        try {
          isEnabled = this.enabled;
          console.log("AFTER this");
        } catch(err) {
          console.log("ERR calling this ", err);
        }
        if (!isEnabled) {
          return;
        }
        console.log(label, value);
      }
    };
    
    export default logger;

    By using a regular function, this will be bound to the logger object, and you’ll be able to access the enabled property correctly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search