Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular material slide toggle capturing state

I've got a fairly basic slide toggle. I'd like to perform an HTTP call once the slider has been toggled and in case my HTTP call fails, revert it back to the initial value. I've done it as follows:

import { Component } from '@angular/core';
import { MatSlideToggleChange } from '@angular/material';
import { FakeService } from './fake.service';

@Component({
  selector: 'slide-toggle-configurable-example',
  templateUrl: 'slide-toggle-configurable-example.html'
})
export class SlideToggleConfigurableExample {
  isChecked = false;
  isCheckedInit = false;

  constructor(private readonly fakeService: FakeService) {}

  onChange(value: MatSlideToggleChange) {
    const { checked } = value;

    this.fakeService.throwUp(checked).subscribe(
      () => {},
      () => {
        this.isChecked = this.isCheckedInit;
      }
    );
  }
}

However, this doesn't work. My template looks like that:

<mat-slide-toggle
    (change)="onChange($event)"
    [checked]="isChecked">
  Slide me!
</mat-slide-toggle>
<section>
  {{ isChecked }}
</section>

But isChecked value never changes and is always being displayed as false.

It seems that nothing I'm doing on isChecked field changes its' value.

Here is a Stackblitz to show current behavior.

What do I have to change in order to get desired behavior?

like image 970
Evaldas Buinauskas Avatar asked Dec 13 '22 13:12

Evaldas Buinauskas


1 Answers

The first thing to do is to bind to ngModel instead of checked, with 2 way binding, like so:

<mat-slide-toggle
    (change)="onChange($event)"
    [(ngModel)]="isChecked">
  Slide me!
</mat-slide-toggle>

Secondly, you need to add wrap the this.isChecked = this.isCheckedInit; in a setTimeout, so that it doesn't set it to false until material is finished.

setTimeout(() => this.isChecked = this.isCheckedInit, 0);

Here is a Stackblitz demo

like image 145
user184994 Avatar answered Dec 28 '22 09:12

user184994