skip to Main Content

I’m trying to create a reusable switcher component whose state won’t be changed immediately when clicked, but after an API call is made in parent component – if there is no error, the state will be changed, while when there is an error, the state will remain unchanged.

The problem occurs when the checkbox state is updated from the parent level, the @Input value is updated correctly, but the checkbox state remains unchanged.

Simple reproduction of the problem at the link below:
stackblitz-checkbox-issue

I tried to use ChangeDetectorRef after updating the @Input value, ngModel bindinig, but to no avail.

Any ideas what to do to update the checkbox state from the parent level to work properly?

2

Answers


  1. Your code works if you change the value of checked under the subscribe to the API, To simulate you can declare an object or a service

    export const service:any={
      getData:()=>of(Math.random()>.5?true:false).pipe(delay(500))
    }
    

    And use some like, e.g.

      //main.ts
      toggleSwitcher(e: boolean) {
        service.getData().subscribe((res:any)=>{
          console.log(res)
          if (res)
            this.isChecked = !this.isChecked;
        })
      }
    

    I forked your stackblitz

    NOTE: You can also force to redraw the app

    toggleSwitcher(e: boolean) {
        setTimeout(()=>{
          this.isChecked = !this.isChecked;
        })
    }
    
    Login or Signup to reply.
  2. You are in a complicated way…
    You need to know all about angular tools…
    You need to split the functionality and set in the rigth place…

    So…

    Your checkbox component must be reponsable for api call and then propagate the response for all components of your application…

    If your component has childen the use @Input un your children.
    If your component has parent use EventEmitter in simple way
    If your component has parents, children, brothers compontens, use Suject/Behavior-Subject

    Try to do something like this, you will gain maintaining, time, readability, good practice, ease communication, and save cost:

    export class SwitcherComponent implements OnInit {
      @Input() isChecked: boolean = false;
    
      constructor() // you need inject your service here
      {}
    
      ngOnInit() {}
    
      onSwitcherClick(e: any) {
        console.log('clicked');
        e.preventDefault();
        service.getData().subscribe(
          (res: any) => {
            console.log(res);
            if (res) this.isChecked = !this.isChecked;
            // this.toggleSwitcher.emit(this.isChecked); // <= Dont use this aproach any more
            // you need create a subject comunication services for propagate to all components the response, 
          }
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search