Do arrow functions have specific implications when it comes to the context of Angular Components?

The topic of arrow functions is commonly discussed, but I've been unable to find an answer to the following scenario.

Let's consider this example from an Angular 4 Directive:

export class MouseParallaxDirective implements AfterViewInit {

constructor(private element: ElementRef) {
}

ngAfterViewInit() {
    // In this case, `this` refers to the angular component object
    let movementStrength = 25;
    let height = movementStrength / window.innerHeight;
    let width = movementStrength / window.innerWidth;
    let parallaxElement = this.element.nativeElement;

    window.onmousemove = (e) => {
        // Here, `this` should refer to the same object as per function scope preservation by arrow function
        let pageX = e.pageX - (window.innerWidth / 2);
        let pageY = e.pageY - (window.innerHeight / 2);
        let newvalueX = width * pageX * -1 - 25;
        let newvalueY = height * pageY * -1 - 50;
        parallaxElement.style.backgroundPosition = newvalueX + "px " + newvalueY + "px";
    };

}
}

Shouldn't both instances of this point to the identical object when using an arrow function to maintain the outer scope?

Answer №1

When the ngAfterViewInit method is called from within the MouseParallaxDirective class, it follows the prototype pattern, meaning that this refers to the specific instance of the class.

The context of this is determined dynamically, prompting us to question, "What is the object calling this function?"

There are four rules for understanding the context of this:

  1. If a function exists in the global scope, then this will point to the window object (only in non-strict mode).
  2. When a function is preceded by an object's name and dot notation, like myObj.myFunc()
    The object before the dot becomes this (myObj === this in this scenario).

  3. Usage of .call, .apply, or .bind explicitly defines this. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#The_bind_method

  4. In the case of using a constructor function (with the keyword new), this points to the specific instance generated and returned by the said constructor function.

With the introduction of ES2015, Arrow functions operate differently, no longer defining this dynamically.

this now maintains the value of the enclosing LEXICAL context's this...

An important note is that arrow functions should not be used when adding functions to a prototype, as they prevent proper usage of this. For instance, avoid implementing the following pattern:

Array.prototype.mySort = () => {// this is not referenced to the array}

In your scenario, the anonymous arrow function within window.onmousemove relates to the class instance due to its lexical context.

Answer №2

The onmousemove method is associated with the window object, so within this function, the reference to this will point to the window object.

Similarly, the ngAfterViewInit function is defined within the scope of the MouseParallaxDirective component, meaning that in this case, this refers to that specific component.

Therefore, the two instances of this cannot be referencing the same object in this scenario.

However, it is still possible to access variables from the outer scope, as demonstrated by being able to access a variable declared within the component inside the onmousemove function.

https://i.sstatic.net/P5XWh.jpg

In order to access the component’s scope, a new variable named _this is created.

Scopes:

https://i.sstatic.net/8Q9Jk.jpg

Demo:

https://stackblitz.com/edit/angular-5u6zid?file=app/mouseParallaxDirective/MouseParallaxDirective.component.ts

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

Angular2 Routing error. Index 1 in the requested path is undefined

Having trouble with routing in Angular 2. I am calling router.navigate from an action within a data table. The strange thing is that sometimes when I click the button to trigger this line, it works perfectly fine, but other times it doesn't. this.rou ...

Discover the steps to implement user authentication with a combination of username, password, and token in an Angular 4

After developing a form using Angular 4, I encountered the need to send the form data via the post method with Angular 4. Testing with Postman showed that the data is being received correctly. To accomplish this, I must use Basic Auth with a username and p ...

I am facing an issue with the Angular2 Modal Form where it only displays the data but does

Hey there, I recently started diving into Angular and I'm loving the learning process. Currently, I've managed to successfully load a form into my Modal when clicking on "viewDetails". However, as soon as I modify the Form from <form ngNoFo ...

Is there a way to insert data from one table into a MySQL Table in Drizzle and update the entry if it already exists?

My goal is to utilize Drizzle for inserting data into a table and updating it if the key already exists. In MySQL, the code would look like this: INSERT INTO myTable1(field1,field2,field3,field4) SELECT fieldOne,fieldTwo,fieldThree,fieldFour FROM myTable2 ...

angular2 and ionic2 encounter issues when handling requests with observable and promises

I am attempting to trigger an action once a promise request has been resolved, but I'm having trouble figuring out how to achieve this. After doing some research, I learned that Ionic2 storage.get() returns a promise, and I would like to make an HTTP ...

Having trouble loading extensive amounts of data into a select element within an Angular application

Upon successfully retrieving around 14000 data entries from an HTTP request, I am facing difficulties loading this vast amount of data into my Select Tag. This is causing the entire page to slow down. The structure of the select Tag in question is as follo ...

Styling array of arrays

When retrieving data from an API, the structure looks like this: "key1" : { "subkey1" : value "subkey2" : value "subkey3" : value } "key2" : { &q ...

The latest update of WebStorm in 2016.3 has brought to light an error related to the experimental support for decorators, which may undergo changes in forthcoming

Hello, I recently updated to the latest WebStorm version and encountered this error message: Error:(52, 14) TS1219:Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' ...

Developing collaborative functions in Angular

Is there a way in Angular 9 to directly call static methods from HTML without using shared services or defining methods in components? I came across an old approach on How to call static method of other class in .html (not in .ts)?, but I am curious if the ...

Error encountered when trying to match routes in two separate Angular applications within an Express app: "Cannot find any routes that match

Greetings (please pardon any language errors as English is not my first language) Like many others, I have an Angular app running in Express and decided to create separate Angular apps for the admin and users (mainly because the navigation bar was becomin ...

Steps for TS to infer types on interfaces

Incorporated in my React application is an object that I devised. Within this object, there is the following definition for Props: type Props = { message: MessageTypes | MessageImgTypes; showTimeStamp: boolean; } If we assume that MessageTypes consists o ...

Tips for finding the displayRows paragraph within the MUI table pagination, nestled between the preceding and succeeding page buttons

Incorporating a Material-UI table pagination component into my React application, I am striving to position the text that indicates the current range of rows between the two action buttons (previous and next). <TablePagination ...

Identifying the Click Event Within an ngx Bootstrap Modal

I recently set up an ngx bootstrap modal using the instructions provided in this helpful guide - . However, I'm facing a challenge in detecting click events within the modal body once it's open. Below is the code snippet from my app component. D ...

Make sure to load Meteor.user() prior to initializing Angular 2

I am encountering an issue while setting up a new Meteor - Angular2 application where I am struggling to verify the logged-in user within my router. Below is my current auth-guard.service.ts content featuring an AdminAuthGuard that utilizes implements Can ...

Explaining the distinction between include and rootDir in tsconfig.json

According to the information provided, include defines an array of filenames or patterns that are to be included in the program during the compilation process. On the other hand, rootDir specifies the path to the folder containing the source code of the ap ...

Angular 6 offers a versatile multi-select dropdown feature

Looking to select multiple values in Angular 6 using checkboxes. When selecting a department from the dropdown, a list of employees related to that department is displayed in another dropdown with checkboxes. However, only the last value of the array app ...

Error message in Angular2 for production build with webpack: "Unable to load app/app.component.html"

My current project is utilizing Angular2-webpack-starter, running on Angular2 rc.4 and webpack 1.13.1. Everything functions smoothly in dev mode. https://i.sstatic.net/4r8B3.png However, when attempting to switch to production mode, I encounter the error ...

Prevent the "Ok" button from showing on the keyboard in an Ionic 2 form

I developed an innovative Ionic 2 application with a form feature. Within my forms, there is the option to input type "text", which naturally prompts the device's keyboard to appear. However, I encountered an issue where pressing the "Ok" button on th ...

Compiling Typescript upon saving in Sublime Text 3

Seeking a solution: How can I get Sublime Text 3 to automatically compile Typescript code when I save it? Having to switch between the terminal and Sublime is getting tedious. Appreciate any advice, thank you! ...

Is there a way to ensure that Tailwind CSS loads before rendering components in NextJS?

While developing my web application, I encountered an issue with the tailwind CSS styling. The styles seem to load correctly, but there is a slight delay before they take effect. This results in users seeing the unstyled version of the website briefly befo ...