Unclear on the usage of "this" in arrow functions?

After going through various discussions and articles on this topic, I find myself still perplexed about the meaning of this in arrow functions.

I've been encountering run-time errors with a code snippet similar to the following:

export class Foo implements OnInit {
myProp: string;
myKeys: Array<any> = [];
mySubKeys: Array<any> = [];
@Input myObj;

. . . 

ngOnInit() {

this.myKeys = Object.keys(this.myObj); 
this.myKeys.forEach((key) => {
    this.myProp = key;
    this.mySubKeys = Object.keys(this.myObj[key]);
    this.mySubKeys.forEach((subkey) => { . . .  
. . . 

The issue arises at this.myProp = key where the debugger indicates that this is undefined.

I'm under the impression that in arrow functions, this refers to the this preceding the scope within which the arrow function is called. In this scenario, shouldn't the preceding scope be the class, making this.myProp valid?

Attempting to change the arrow function to forEach(function(key) { . . . resulted in different errors.

So if the this inside the arrow function doesn't point to the class this, how can I access the class this along with its properties (like myProp) from within the arrow function?

Answer №1

One of the main reasons for this issue is that the value of this within a function is dependent on how the function is invoked.

For instance, if the function is called as this.myKeys.forEach(), then the value of this will be the calling context, which in this situation is myKeys.

However, it's important to note that it won't always be

myKeys</code. Therefore, trying to access <code>this.myProp & this.mySubKeys
might not return value - instead, it could result in an undefined value or trigger an error.

The unpredictability of this is a common challenge in the world of Javascript and has been a longstanding issue.

In ES5, there are several techniques available to handle and stabilize the value of this. One popular approach is to assign this to another variable at the beginning, often referred to as self, and then consistently utilize self within the function body, like so:

ngOnInit() {


   this.myKeys = Object.keys(this.myObj) {

    let self = this; // declare the variable to refer class object
    this.myKeys.forEach((key) => {
        self.myProp = key;
        self.mySubKeys = Object.keys(this.myObj[key]);
        self.mySubKeys.forEach((subkey) => { . . .  
   . . . 

Hopefully, this explanation proves to be helpful!

Answer №2

The usage of this in the provided code should function as intended. It appears that the issue lies within this specific line:

this.myKeys = Object.keys(this.myObj) {

There seems to be an unnecessary opening { instead of a closing ;.

this.myKeys = Object.keys(this.myObj);

The corrected code snippet should resemble:

ngOnInit() {
    this.myKeys = Object.keys(this.myObj);
    this.myKeys.forEach((key) => {
        this.myProp = key;
        this.mySubKeys = Object.keys(this.myObj[key]);

Update:

A demo has been included for testing to ensure that the functionality of this is correct: https://stackblitz.com/edit/stackoverflow-mykeys-demo

Please note that the Input() must also include the ().

Answer №3

According to the MDN website:

Arrow functions do not have their own 'this' binding. Instead, they inherit the 'this' value from the surrounding lexical scope; arrow functions adhere to the standard variable lookup rules. Therefore, when attempting to access 'this' in a scope where it is not defined, arrow functions will look to its enclosing scope for the 'this' value.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a getMacChromiumEdgeDriverArchitecture error while using wdio/selenium-standalone-service

As I continue to learn WebDriverIO and adjust to MacOS, I encountered an error while trying to execute a spec file using "npm run test:wdio". The error message is as follows: > [email protected] test:wdio /Users/vinicius.correia/Desktop/dev/automat ...

Extension: What is the best way to leverage data obtained from an ajax request in order to dynamically modify an already existing element within

I've been trying to find a reliable and comprehensive tutorial for JavaScript (JS) and Ajax, but so far my search has been futile. Unlike Python.org for Python or php.net for PHP, I haven't found a satisfactory resource yet. Any recommendations w ...

Is the Three.JS camera update causing issues with the shader?

Attempting to replicate the Bubble shader from https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Bubble.html, but encountering issues due to outdated code. The example should refract whatever is behind it, like this: https://i.sstatic ...

several parameters for the `ts-node -r` options

Can I include multiple require statements in the package.json script before running with ts-node -r? "scripts": { "start": "ts-node -r dotenv/config newrelic src/index.ts", } I'm having trouble adding both "dotenv/config" and "newrelic" si ...

Using JavaScript promises to handle connection pooling and query execution

I am contemplating whether this approach is on the right track or if it requires further adjustments. Should I consider promisifying my custom MySQL getConnection method as well? request: function(queryRequest) { return new Promise(function(re ...

What is the best way to set up a session using jQuery?

I've been troubleshooting my code and I can't seem to figure out why the jquery.session.js file isn't working. Can someone help me find a solution? $.session.set('rmng_time', remaining_seconds); alert("j session "+$.sessi ...

Access the information from the text box and text area, then store it into a cookie using either jQuery or JavaScript

I need to save the text entered in a textbox within an iframe. How can I achieve this using jQuery or JavaScript? Any assistance would be greatly appreciated. ...

Extracting data on an AngularJS platform by using web scraping techniques

I have been working on an AngularJS application that currently retrieves JSON data from an API using http.get, and it's been working really well. Recently, I've been exploring the idea of passing a URL to a static webpage and scraping the result ...

The Angular template driven forms are flagging as invalid despite the regExp being a match

My input looks like this: <div class="form-group"> <label for="power">Hero Power</label> <input [(ngModel)]="model.powerNumber" name="powerNumber" type="text" class="form-control" pattern="^[0-9]+$"id= ...

What is the purpose of importing a module in app.module.ts? And what specifically happens when importing classes one by one in the

I am interested in creating an Angular form, but I have a question about why we import 'ReactiveFormsModule' in app.module. Additionally, I am curious as to why we need to explicitly import classes like FormControl and FormGroup again in the temp ...

Creating a sleek horizontal drop-down navigation menu using Bootstrap 5 and CSS

Attempting to design a horizontal dropdown menu for small screens has been a challenge. However, all the resources I've come across seem to be outdated and ineffective. ...

Sorting through an array using a different array of values

Looking to filter one array with another, where values in the first array should match 'id' in the second array for filtering. The arrays in question are: const array1 = [a, b, c, d] The array to be filtered based on matching 'id' va ...

What is the designated action or code in question?

let specialty = ''; function isVegetarian() { }; function isLowSodium() { }; export { specialty, isVegetarian }; export { specialty, isVegetarian }; The explanation from the editor was as follows: When exporting objects, it is done by the ...

The attempt to update several partial views using Jquery, MVC, and Json is currently malfunctioning

I am facing issues with updating multiple partial views using jQuery, MVC, and JSON. The partial views on my page are not getting updated. Below is the code for my view: Here is the code for my controller: public class GetStudentsController : Controlle ...

When a function is called, retrieve a specific number of elements from an array using the slice method in

If I have an array of 15 objects, but I am only displaying 5 on the browser using this code: const displayedArray = array.slice(0,4) I also have a function that will load another 5 objects each time a user scrolls down. displayedArray.concat(array.slice ...

Display or Conceal Content Depending on the Button's Status

I am currently working on implementing an accordion style button for a project. I have configured my component to hide the list when the button is clicked, but I am encountering an issue where the list does not reappear. Additionally, I would like to inc ...

How do I set up middleware with async/await in NestJS?

I am currently integrating bull-arena into my NestJS application. export class AppModule { configure(consumer: MiddlewareConsumer) { const queues = this.createArenaQueues(); const arena = Arena({ queues }, { disableListen: true }); consumer. ...

Mastering the art of utilizing middleware in every HTTP request using Node.js Express

I am currently developing a middleware for my nodejs application and I need to include a header in the request within the middleware before sending it to my index.js endpoint. middleware1.js exports.mw1 = function(req, res, next) { next(); }; middlewa ...

Error: The function Undefined is not recognized by express.io

Struggling to configure express.io with individual files for each route? Check out the examples provided. Currently, I have a typical Express setup that I want to transition to express.io: Project app.js routes servepage.js Views ...

Creating a custom class implementation in JavaScript and initializing it with a constructor function

Perhaps there is a similar question out there, but I haven't come across it yet and I'm still facing an issue. Here's what I've tried: function createClass(obj) { const constructor = obj.constructor; constructor.prototype = obj; ...