What is the best way to incorporate this in a callback function?

Utilizing a third-party component requires creating an object for configuration, such as itemMovementOptions in the given code sample.

export class AppComponent implements OnInit {
    readonly itemMovementOptions = {
      threshold: {
        horizontal: 25,
        vertical: 25,
      },
      events: {
        onMove({ items }) {
          for (let i = 0, len = items.after.length; i < len; i++) {
            const item = items.after[i];
            if (!this.canMove(item)) return items.before;
          }
          return items.after;
        },
      },
    };

    public canMove(item) {
       // ...
    }

    readonly config = {
        ItemResizing(this.itemResizeOptions),
        ItemMovement(this.itemMovementOptions),
    }

    ngOnInit(): void {
      GSTC.api.stateFromConfig(this.config);
    }
}

The issue arises when the code is executed and 'this' does not reference AppComponent, causing it to fail to find the method canMove().

I need help overcoming this problem. I must use canMove at multiple places without duplicating code or putting it into the callback.

Answer №1

this concept can be tricky for those new to JavaScript:

  • With regular functions, the value of this is determined by the call context.
  • Arrow functions bind the value of this at the time of creation, not when invoked.

Consider the following example:

class AppComponent  {
  onMoveFunction() {
    console.log("From onMoveFunction", this);
  }

  onMoveArrow = () => {
    console.log("From onMoveArrow", this);
  }
}

const c = new AppComponent();
const callbackFunction = c.onMoveFunction
const callbackArrow = c.onMoveArrow

c.onMoveFunction() // "From onMoveFunction",  AppComponent: {} 
c.onMoveArrow()    // "From onMoveArrow",  AppComponent: {} 
callbackFunction() // "From onMoveFunction",  undefined 
callbackArrow()    // "From onMoveArrow",  AppComponent: {} 

Another approach is to utilize bind().

For further reading:

Answer №2

When it comes to the content of your canMove() function, there are two options available:

  1. If the canMove() function does not have any references to this within its logic, meaning it is independent of the class or component it resides in, like this example:

    app.component.ts

    canMove(item): boolean {
      return item.canMove;
    }
    

    In such cases, the function can be made static and referenced as shown below:

    app.component.ts

    static canMove(item): boolean {
      return item.name;
    }
    
    ...
    if (!AppComponent.canMove(item)) return items.before;
    ...
    

    Please note that this approach also applies if the function is located outside the component class, for instance:

    utilities.ts

    class Utilities {
      static canMove(item): boolean {
        return item.name;
      }
    }
    

    app.component.ts

    ...
    if (!Utilities.canMove(item)) return items.before;
    ...
    
  2. On the other hand, if the canMove() function does contain references to this, indicating its dependency on some class/component content, like in this example:

    app.component.ts

    canMove(item): boolean {
      return item.canMove && this.canMoveOverride;
    }
    

    In such situations, the originating class context needs to be provided to the function when referencing it so that all necessary this. variables (defined in AppComponent) are accessible. This can be achieved using the .bind() method (docs)

    app.component.ts

    ...
    if (!this.canMove(item).bind(this)) return items.before;
    ...
    

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

Obtaining the component instance ('this') from a template

Imagine we are in a situation where we need to connect a child component property to the component instance itself within a template: <child-component parent="???"></child-component1> Is there a solution for this without having to create a sp ...

The Angular Material Theme is not being properly displayed on the mtx-datetimepicker component

Issue: While using directives from ng-matero for DateTime with Angular Material for application design, the dateTimepicker element is not applying the angular material theme as desired. https://i.sstatic.net/zPBp3.png Code Example The app.module.ts file i ...

What is the best way to combine an Angular project with an existing Node.js project?

I've successfully deployed my Angular project on Heroku and my Node.js API REST on Heroku as well. However, they are separate projects with different URLs but function together. Is there a way to combine them on the server and have just one URL? Curr ...

Component declaration in Typescript is being rejected due to the union type not being accepted

In my current project, I'm working on a component that should accept either an onClick or a to prop. const StickyButton: React.FC< ({ onClick: MouseEventHandler } | { to: string }) & { buttonComponent?: ({ onClick: MouseEventHandler }) =& ...

String defines the type

I came across the following code snippet in some external sources that I intend to incorporate into my project: const INIT: 'jsonforms/INIT' = 'jsonforms/INIT' Can someone explain what it means to define a type with a string like INIT ...

How can you merge arrays in Angular based on their unique names?

Is there a way to combine objects within the same array in Angular based on their names? [{ "name":"Navin", "id":"1" }, { "name":"Navin", "mark1":"98" ...

Limit the category to a specific subset of strings

Looking for a way to implement literal type restrictions without using type aliases: const foo = (a: 'string', b: 'string') => { } foo("123", "abc") // should fail foo("123" as 'string', "abc" as 'string') I pr ...

I'm having trouble linking MikroORM migration to Postgresql - the npx command keeps failing. Can anyone offer some guidance on what

I am encountering a situation similar to the one described in this post. I'm following Ben Awad's YouTube tutorial: you can see where I am in the tutorial here. Objective: My goal is to execute npx mikro-orm migration:create in order to generate ...

Why are polyfills-es2015, vendor-es2015, main-es2015, and other files blocked from loading because the MIME type is not allowed (text/html

Hey there! I've encountered an issue during the deployment of my Angular app. When I serve it from Angular locally, everything works perfectly fine. However, when I deploy it on a Tomcat server, I encounter errors and I can't see anything related ...

Getting the parent from a child in Typescript: Best Practices

Querying: In TypeScript, is it possible to retrieve a parent instance from a child instance? I am aware that casting a child into its parent is a method, however, the child's additional properties still exist in the parent, albeit concealed. Check o ...

Personalized context hook TypeScript

I have been experimenting with a custom hook and the context API, based on an interesting approach that I found in this repository. However, I encountered an error when trying to use it with a simple state for a number. Even though I wanted to create a mo ...

Watching multiple Angular libraries for changes and serving to a separate application on the go

Currently, I am working on developing three Angular libraries that will be consumed by another main application. My goal is to have live rebuilding for the libraries while my main app imports and runs them simultaneously. This way, I can achieve live reloa ...

Having trouble locating modules or properties with ANTLR4 TypeScript target?

Having reached a frustrating impasse, I am seeking assistance with a perplexing issue. My attempt to integrate TypeScript with ANTLR4 has hit a snag, and despite exhaustive efforts, I am unable to pinpoint the root cause (with limited documentation availab ...

The element in the iterator in next.js typescript is lacking a necessary "key" prop

Welcome to my portfolio web application! I have created various components, but I am facing an issue when running 'npm run build'. The error message indicates that a "key" prop is missing for an element in the iterator. I tried adding it, but the ...

The incorrect type is being assigned to an array of enum values in Typescript

Here's some code that I've been working on: enum AnimalId { Dog = 2, Cat = 3 } const animalIds: AnimalId[] = [AnimalId.Dog, 4]; I'm curious as to why TypeScript isn't flagging the assignment of 4 to type AnimalId[]. Shouldn't ...

Currently, I am working on integrating the ngx-bootstrap datepicker feature into my project

I'm currently working on integrating the ngx-bootstrap datepicker and would like to display the months as Jan, Feb, Mar, Apr instead of January, February. How can I achieve this customization? ...

The parameter "path" must be a string type. Instead, we received type undefined. This issue is specific to Ionic 4 on Windows

Encountered an unexpected error that is hindering development on a Windows PC, even though building the app works fine on a Mac. The error message received is: cordova build android --stacktrace config file undefined requested for changes not found at ...

Using TypeScript with knockout for custom binding efforts

I am in the process of developing a TypeScript class that will handle all bindings using Knockout's mechanisms. Although I have made progress with the initial steps, I have encountered a roadblock. While I can successfully bind data to my HTML element ...

Ionic JavaScript function runs independently of promise resolution

Within my ngOnInit on a page, I have a method that is meant to fetch data. However, it seems like the other methods in the chain are executing before the fetch data process is complete. Here's a snippet of the code: ngOnInit() { this.devicesinfo.fetc ...

Learn how to resubscribe and reconnect to a WebSocket using TypeScript

In my Ionic3 app, there is a specific view where I connect to a websocket observable/observer service upon entering the view: subscribtion: Subscription; ionViewDidEnter() { this.subscribtion = this.socket.message.subscribe(msg => { let confi ...