Mohamed
Mohamed

Reputation: 1271

Using Ionic2 toggle with firebase

I have list of users, and I want to enable/disable them.

I have firebase list binded to ion-list

  constructor(public navCtrl: NavController,
              private af: AngularFire,
              public cartService: CartService) {
    this.users = af.database.list('/users')
  }

  toggleUserStatus(user) {
    this.users.update(user.$key, {isActive: user.isActive})
      .then(_ => this.cartService.showToast('User ' + ((user.isActive) ? 'Enabled' : 'Disabled')))
      .catch(err => this.cartService.showToast(err));
  }

template;

<div *ngFor="let user of users|async">
  <ion-item padding>
    <ion-label>{{user.fullName}}</ion-label>
    <ion-toggle tappable (ionChange)="toggleUserStatus(user)" [(ngModel)]="user.isActive"></ion-toggle>
  </ion-item>
</div>

However it doesn't work. Its toggling again and again again.

How can I make this work?

Thank you.

Upvotes: 0

Views: 560

Answers (1)

whatsthatitspat
whatsthatitspat

Reputation: 721

I'm guessing you worked around this, but for anyone else, I find a lot of issues with ionChange (for ion-toggles, ion-datetime, and other Ionic components) when working with observables. I'd stick to ngModelChange instead.

If you're going to bind to a change event with ionChange/ngModelChange, just use the brackets for the model, i.e. just [ngModel]="user.isActive" instead of [(ngModel)]="user.isActive". Otherwise, the banana-in-a-box is trying to change the model too.

And use a trackBy function when you have a list that changes so only the item that changes gets rewritten in the DOM.

Also, you don't need tappable.

<div *ngFor="let user of users$ | async; trackBy:trackByFn;">
  <ion-item padding>
    <ion-label>{{user.fullName}}</ion-label>
    <ion-toggle
    [ngModel]="user.isActive"
    (ngModelChange)="toggleUserStatus($event, user)">
    </ion-toggle>
  </ion-item>
</div>

//-----------

toggleUserStatus(isChecked, user) {
  this.users
  .update(user.$key, {isActive: isChecked})
  .then(_ => {
    // show toast
  })
  .catch(err => {
    // show error
  });

trackByFn = (idx, obj): string => obj.$key;

Upvotes: 1

Related Questions