Skip to content

Failed resolving method setChecked on class android.widget.Switch #943

Closed

Description

@NickIliev

From @LunicLynx on August 14, 2017 22:49

The Problem

When using an ngIf on a StackLayout including a Switch like so:

<StackLayout *ngIf="data | async; let data">
    <Switch [(ngModel)]="data.toggle"></Switch>
</StackLayout>

Using a two-way binding. One will get the following error:

JS: ERROR Error: java.lang.Exception: Failed resolving method setChecked on class android.widget.Switch
JS:     com.tns.Runtime.resolveMethodOverload(Runtime.java:1004)
JS:     com.tns.Runtime.callJSMethodNative(Native Method)
JS:     com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1043)
JS:     com.tns.Runtime.callJSMethodImpl(Runtime.java:925)
JS:     com.tns.Runtime.callJSMethod(Runtime.java:912)
JS:     com.tns.Runtime.callJSMethod(Runtime.java:896)
JS:     com.tns.Runtime.callJSMethod(Runtime.java:888)
JS:     com.tns.gen.java.lang.Runnable.run(Runnable.java:10)
JS:     android.os.Handler.handleCallback(Handler.java:733)
JS:     android.os.Handler.dispatchMessage(Handler.java:95)
JS:     android.os.Looper.loop(Looper.java:136)
JS:     android.app.ActivityThread.main(ActivityThread.java:5001)
JS:     java.lang.reflect.Method.invokeNative(Native Method)
JS:     java.lang.reflect.Method.invoke(Method.java:515)
JS:     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
JS:     com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
JS:     dalvik.system.NativeStart.main(Native Method)

This seems to be a general problem with ngModel and Switch, whenever the value gets lazily initialized this error seems to happen.

Platforms

Android

Versions

  • CLI: 3.1.3

package.json

{
	"description": "NativeScript Application",
	"license": "SEE LICENSE IN <your-license-filename>",
	"readme": "NativeScript Application",
	"repository": "<fill-your-repository-here>",
	"nativescript": {
		"id": "org.nativescript.ngIfSwitchIssue",
		"tns-android": {
			"version": "3.1.1"
		}
	},
	"dependencies": {
		"@angular/animations": "~4.2.0",
		"@angular/common": "~4.2.0",
		"@angular/compiler": "~4.2.0",
		"@angular/core": "~4.2.0",
		"@angular/forms": "~4.2.0",
		"@angular/http": "~4.2.0",
		"@angular/platform-browser": "~4.2.0",
		"@angular/router": "~4.2.0",
		"nativescript-angular": "~4.2.0",
		"nativescript-theme-core": "~1.0.2",
		"reflect-metadata": "~0.1.8",
		"rxjs": "~5.4.2",
		"tns-core-modules": "~3.1.0",
		"zone.js": "~0.8.2"
	},
	"devDependencies": {
		"babel-traverse": "6.4.5",
		"babel-types": "6.4.5",
		"babylon": "6.4.5",
		"lazy": "1.0.11",
		"nativescript-dev-typescript": "~0.5.0",
		"typescript": "~2.4.2"
	}
}

Repo that reproduces the error

I created a repo reproducing the error. Just start it and wait for 5 Seconds.
https://github.com/LunicLynx/ns-ngif-switch-ngmodel-async-issue

Copied from original issue: NativeScript/NativeScript#4694

Activity

  1. NickIliev commented on Aug 15, 2017

    @NickIliev
    Author

    From @LunicLynx on August 14, 2017 22:52

    This is a workaround:

    export class AppComponent implements OnInit, OnDestroy {
        subscription: Subscription;
        dataSubject: BehaviorSubject<{ toggle: boolean }> = new BehaviorSubject({ toggle: true });
        data = this.dataSubject.asObservable();
    
        ngOnInit(): void {
            this.subscription = Observable.of({ toggle: false }).delay(5000).subscribe(
                data => {
                    this.dataSubject.next(data);
                }
            );
        }
    
        ngOnDestroy(): void {
            this.subscription.unsubscribe();
            this.subscription = null;
        }
    }

    But i think it should work either way.

  2. NickIliev commented on Aug 15, 2017

    @NickIliev
    Author

    From @EddyVerbruggen on August 15, 2017 8:43

    I'm not sure if it helps for your case, but have you tried this?

    <StackLayout>
        <Switch [(ngModel)]="data?.toggle"></Switch>
    </StackLayout>
  3. sis0k0 commented on Aug 16, 2017

    @sis0k0
    Contributor

    related to #846

  4. added this to the milestone on Aug 16, 2017
  5. LunicLynx commented on Aug 18, 2017

    @LunicLynx

    @NickIliev it's not possilbe to use the ?. operator in two way bindings.

  6. modified the milestones: , on Aug 21, 2017
  7. jarrodchesney commented on Aug 25, 2017

    @jarrodchesney

    This worked for me, I've made the names more generic, but otherwise this is my code.

    My XML/HTML

        <Switch #boolValSw [checked]="obj?.boolVal"            
            (checkedChange)="setBoolVal(boolValSw.checked)" ></Switch>
    

    My TypeScript

        obj = {boolVal:false};
    
        setBoolVal(val:boolean) {
            this.obj.boolVal = val;
        }
    
    
  8. modified the milestones: , on Oct 3, 2017
  9. self-assigned this
    on Oct 10, 2017
  10. deleted a comment from tsonevn on Oct 10, 2017
  11. self-assigned this
    on Oct 11, 2017
  12. removed their assignment
    on Oct 11, 2017
  13. flynsequeira commented on Feb 7, 2019

    @flynsequeira

    Facing this issue with Text Field:
    <TextField hint="Eg. Ford" [(ngModel)]="car.make" class="car-list-even" required>
    and on ngOnInit() I have this.car['make']='Ford' and it crashes with the above error.

  14. justintoth commented on Dec 13, 2021

    @justintoth

    I'm hitting this issue with the Switch widget, this was NOT resolved...

    System.err: An uncaught Exception occurred on "main" thread.
    System.err: Calling js method onCreateView failed
    System.err: Error: java.lang.Exception: Failed resolving method setChecked on class android.widget.Switch
    System.err: 
    System.err: StackTrace:
    System.err: [checked:setNative](file: node_modules/@nativescript/core/ui/switch/index.android.js:67:0)
    System.err:     at applyAllNativeSetters(file: node_modules/@nativescript/core/ui/core/properties/index.js:1137:0)
    System.err:     at initNativeView(file: node_modules/@nativescript/core/ui/core/properties/index.js:1080:0)
    System.err:     at onResumeNativeUpdates(file: node_modules/@nativescript/core/ui/core/view-base/index.js:737:22)
    System.err:     at _resumeNativeUpdates(file: node_modules/@nativescript/core/ui/core/view-base/index.js:280:0)
    
  15. arLevi commented on Apr 14, 2023

    @arLevi

    Wanted to share my workaround until this is resolved, in my case, I had a list of items which next to each I wanted to give a Switch to turn on/off .. it was a part of a list ( for loop ) so I had to have some kind of data-binding for each switch on the items list.

    I wrote it like so:

    # Instead of two-way data binding which result an error above
    <Switch [checked]="item.checked">
    
    # I wrote it as non binding:
    <ng-template let-item="item" let-index="index">
      <StackLayout>
        <Switch checked="{{ item.checked }}">
      </StackLayout>
    </ng-template>
    

    And to answer the above question what was missing for you was also the $event so an example of how I used it as a list vs a single switch - I passed both index and $event to the function:

    # html
    <Switch checked="{{ item.checked }}" (checkedChange)="switched(index, $event)">
    
    # ts
    import { Switch } from "@nativescript/core";
    
    switched(index, args: EventData) {
      let switch_item = args.object as Switch;
      this.my_items_array[index].checked = switch_item.checked;
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions