0

I'm using bootstap switches for checkboxes in my Angular 2 application. When you click on the switch, I want the value of my LightNeeded variable in my class to change along with it. I have the following code:

HTML:

<input class="bootstrap-switch light-needed" name="LightNeeded" type="checkbox" [(ngModel)]="LightNeeded">

TypeScript file:

LightNeeded: boolean;

 ngOnInit(): void {        
    // Invoke bootstrap switches
    $('.bootstrap-switch').bootstrapSwitch({
        onText: "Yes",
        offText: "No"
    });
    this.changeBootstrapSwitchValues();
}

changeBootstrapSwitchValues() {
    $('.light-needed').on('switchChange.bootstrapSwitch', function (event:any, state:any) {
        if (state) {  
            console.log('true');
            this.LightNeeded= true;
        } else {  
            console.log('false');
            this.LightNeeded= false;
        };
    });
}

When switch is true, it successfully logs true to the console. When it is false, it successfully logs false to the console. However, it never changes the value of my LightNeeded variable.

When I hover over this of this.LightNeeded, I get the following warning:

suspicious 'this' usage: in current context 'this' refers to a local function, not to a containing class.

How can I get this to work the way I am intending and change the value of my LightNeeded variable? I'm open to taking other approaches that make sense too. I tried adding [attr.checked]="LightNeeded? true : null" to my input, but it didn't work.

EDIT:

The two-way binding from adding [(ngModel)]="LightNeeded" worked when it was a simple checkbox, but for some reason the bootstrap switch plugin breaks that two-way binding. Other plugins such as JQuery Inputmask and JQuery UI Datepicker also break two-way binding.

Bryan
  • 2,951
  • 11
  • 59
  • 101
  • the value will be changed by two-way binding of the element – Roman C Nov 09 '16 at 23:20
  • It should be, yes, but it isn't. It worked when they were simple checkboxes, but as soon as I implemented the bootstrap switch the two-way binding broke. – Bryan Nov 09 '16 at 23:26
  • Possible duplicate of [TypeScript and this context detection](http://stackoverflow.com/questions/33791128/typescript-and-this-context-detection) – Fiddles Nov 10 '16 at 00:09

3 Answers3

2

Your event handler function changes the context of this. Instead, you should use an arrow function, which does not change context/binding. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Example:

$('.light-needed').on('switchChange.bootstrapSwitch', (event:any, state:any) => {
        if (state) {  
            console.log('true');
            this.LightNeeded= true;
        } else {  
            console.log('false');
            this.LightNeeded= false;
        };
    });
Fiddles
  • 2,790
  • 1
  • 32
  • 35
1

It's all about function scoping. this keyword inside your changeBootstrapSwitchValues() function refers to JQuery object. You can fix this using following technique;

changeBootstrapSwitchValues() {
let self = this;
    $('.light-needed').on('switchChange.bootstrapSwitch', function (event:any, state:any) {
        if (state) {  
            console.log('true');
            //this.LightNeeded= true;
            self.LightNeeded= true;
        } else {  
            console.log('false');
            //this.LightNeeded= false;
            self.LightNeeded= false;
        };
    });
}
0

Maybe is to late but I made a component for angular2+ called jw-boostrap-switch-ng2 if anyone want to check it out.

Is better solution to implement a component because you don't have to worry about JQUERY.

Julio Guerra
  • 390
  • 3
  • 14