3

I have a component with input text field to which I have attached an input event listener using JQuery. When the value of the input changes I want to call a Typescript function but it throws an uncaught TypeError.

Here is my code:

import {Component, Input, Output, EventEmitter, ElementRef, OnInit} from 'angular2/core';
declare var jQuery: any;

@Component({
    selector: 'setting-priority',
    template: '<input [(ngModel)]="priority" class="setting-priority" type="text">'
})

export class SettingPriorityComponent implements OnInit{
    @Input() priority: number;
    @Output() prioChanged: EventEmitter<number> = new EventEmitter();

    constructor(private elementRef:ElementRef) { }

    ngOnInit() {
        jQuery(this.elementRef.nativeElement).find('input').on('input', function() {
            // Here I will pass the changed value to onChange function
            this.onChange();
        });
    }

    ngOnChanges(changes) { 
        this.prioChanged.emit(this.priority);
    }

    // In this function I will receive the value and assign it to the priority variable
    onChange() {
        console.log("onchange!");
    }
}

I'm using Jquery because the input value will be set programmatically - in this case Angular's Change Detection doesn't work Details here

When I trigger the input event, I receive an Uncaught TypeError: this.onChange is not a function

What am I doing wrong?

2 Answers 2

7

I would use an arrow function. This way you could use the lexical this (that corresponds to the component instance):

jQuery(this.elementRef.nativeElement).find('input').on('input', () => {
  this.onChange();
});

See this link for more details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Sign up to request clarification or add additional context in comments.

1 Comment

Works great! Thank you! By the way, I found another one method - to bind a JavaScript variable to the angular context and then call functions using it: var self = this; jQuery(this.elementRef.nativeElement).find('input').on('input', function { self.onChange(); });
2

Try to avoid using jQuery in Angular2.

A more angulary approach to get a reference to an element would be

@Component({
    selector: 'setting-priority',
    template: '<input #prio [(ngModel)]="priority" class="setting-priority" type="text">'
})
export class SettingPriorityComponent implements OnInit{
  @ViewChild('prio') priority;

  ngOnInit() {
    console.log(this.priority);
  }
}

but for adding an event handler you just need:

template: '<input [(ngModel)]="priority" (input)="onChange()" class="setting-priority" type="text">'

1 Comment

Thank you! I'm using Jquery-UI to make a table sortable using drag-and-drop because I didn't find such a simple solution for native Angular 2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.