javascriptangulartypescriptkendo-uikendo-multiselect

Why the attribute value of an Angular class is equal to undefined, inside one of its method, while it is correctly initialized?


In my Angular project I have defined a component called mycomponent. In the html file called mycomponent.component.html I have inserted a kendo multiselect as following:

<kendo-multiselect
    [size]="multiSelectSize"
    [data]="dataList"
    [(ngModel)]="selectedValue"
    [autoClose]="false"
    [clearButton]="true"
    [style.width.px]="644"
    [tagMapper]="mapper"
    (removeTag)="onRemove($event)"                                
    (open)="openFilter()"
>   

    <ng-template kendoMultiSelectTagTemplate let-dataItem>
        <span style="font-size: 11px;">{{ dataItem }}</span>
    </ng-template>

</kendo-multiselect>

In the file mycomponent.component.ts I have defined the method mapper() as following:

export class MyComponent implements OnInit, OnDestroy {

    // MAX_GLOBAL is an attribute of the class MyComponent
    MAX_GLOBAL:number = 8;

    public mapper(tags: string[]) {
        var MAX:number = 4;
        ...
        // code which uses MAX and MAX_GLOBAL
        i = MAX + 2;
        j = this.MAX_GLOBAL + 2;
        ...
    }

}

In this code of mapper() the value of the local variable MAX is 4 (as I expected) while the value of the attribute MAX_GLOBAL is equal to undefined despite the fact that it is correctly set equal to 8 in the attribute definition:

MAX_GLOBAL:number = 8;

In other methods of the class MyComponent I can use attributes of the class MyComponent by this.<attributename>.

For example in the method openFilter() assigned to (open) (see the snippet of code of mycomponent.component.html showed above) I can use correctly attributes of MyComponent.

What's the difference between mapper() and openFilter()?


Solution

  • The mapper is input as a function, depending on where the function is executed, this can take the execution scope, so in this example, the function takes the this (scope) of Kendo Component and not the parent component, hence you are getting the issue.

    openFilter() -> here the function executes on the component HTML.

    [tagMapper]="mapper" -> here the function is not executed, so the scope will change based on the execution context.


    The solution to make the function always execute with the parent scope, no matter where ever the function gets executed, we should use .bind(this) which defines the scope of execution of the method.

    <kendo-multiselect
        ...
        [tagMapper]="mapper.bind(this)"
        ...                              
        (open)="openFilter()"
    >   
        ...
    </kendo-multiselect>