3

I have an Ionic 2 app that allows scheduling notifications (a reminder feature).

Well, the requeriments are:

  • When the user enters into the reminder page, it should check for a saved reminder.
  • If there is a saved reminder (I'm currently saving this info with storage), the clock should be shown with the reminder time saved and the toggle in active state.

  • Else, the clock should be shown with the current time, and the toggle in false state (deactivated).

This works well. I can save reminders and everything works fine, as well as disable them.

The problem occurs when I have a saved reminder and I enter the page, it shows me the notification of "Reminder saved" and of course, what actually happens is that, when I enter to that page, it first corroborates if there is a saved reminder, and if it's true, the toggle is activated. This toggle is linked to the event (ionChange) since it is the one I use to handle the activation / deactivation of the reminder. Then every time I enter the page and there is a saved reminder, it sets the toggle to true, and then as default it initializes to false and (ionChange) detects that there was a change, the event is triggered again, that's why it ends me Saving the reminder again.

It is not that bad, but it should not to save the reminder every time I enter.

I was thinking about using the click event instead of ionChange, but it did not work.

This is my code:

HTML:

<ion-content padding>
    <div class="selector">
        <ion-item>
            <ion-label>Recordatorio</ion-label>
            <ion-toggle class="toggle" [(ngModel)]="toggleStatus" checked="true" (click)="changeToggle()"></ion-toggle>
        </ion-item>
        <ion-item>
            <ion-label>Horario</ion-label>
            <ion-datetime
                pickerFormat="HH:mm"
                [(ngModel)]="time"
                (ngModelChange)="timeChanged()"
                cancelText="Cancelar"
                doneText="Aceptar">
            </ion-datetime>
        </ion-item>
    </div>
</ion-content>

Typescript:

    ionViewWillEnter(): void {

        this.setDefaultProperties();
    }

    public setDefaultProperties(): void {

        this.date = new Date();
        this.setDefaultPickerTime();
        this.setToggleStatus();
    }

    public setDefaultPickerTime(): void {

        this.storage.get('reminderTime')
            .then((result) => {

                if (result) {
                    this.time = result;
                } else {

                    let actualTime: string = this.actualFormattedTime();
                    this.time = actualTime;
                }
            })
            .catch((err) => {
                console.log(err);
            });
    }

    public setToggleStatus(): void {

        this.storage.get('reminderToggleStatus')
            .then((result) => {
                this.toggleStatus = result;
            })
            .catch((err) => {
                console.log(err);
            });
    }

    public timeChanged(): void {

        if (this.toggleStatus === true) {
            this.saveReminder();
        }
    }

    public changeToggle(): void {

        if (this.toggleStatus === true) {
            this.saveReminder();
        } else {
            console.log("deselecciono");
            this.deleteReminder();
            this.deleteStoredReminderData();
            this.showDeleteReminderMsg();
        }
    }

    public deleteReminder(): void {

        LocalNotifications.cancelAll()
            .then((succes) => {
                //
            })
            .catch((err) => {
                console.log(err);
            });
    }

    public deleteStoredReminderData(): void {

        this.storage.remove('reminderTime')
            .then(() => {
                console.log("Tiempo eliminado");
            })
            .catch((err) => {
                console.log(err);
            });

        this.storage.remove('reminderToggleStatus')
            .then(() => {
                console.log("Toggle status eliminado");
            })
            .catch((err) => {
                console.log(err);
            });
    }

    public timePicked(): boolean {

        if (this.time) {
            return true;
        } else {
            return false;
        }
    }

    public saveReminder(): void {

        if (this.timePicked()) {

            var scheduleDate = new Date(this.actualDate() + ' ' + this.time);

            LocalNotifications.schedule({
                id: 1,
                text: '¡Hora de meditar!',
                //at: new Date(new Date().getTime() + 5),
                at: scheduleDate,
                sound: 'file://audio/sound.mp3',
                every: "day",
                //data: { message : 'Informacion' },
                //icon: 'res://icon',
                //smallIcon: 'res://ic_popup_sync'
            });

            this.persistToggleStatus();
            this.persistTime();
            this.showSavedReminderMsg();
        } else {
            this.showNoTimePickedError();
            setTimeout(() => {
                this.toggleStatus = false;
            }, 100)
        }

    }

    public persistToggleStatus(): void {

        this.storage.set('reminderToggleStatus', this.toggleStatus);
    }

    public persistTime(): void {

        this.storage.set('reminderTime', this.time);
    }

I only included the relevant code..

In short: I need to know if I can fire (ionChange) only from the view and prevent it from being activated when it detects a change in the model, from the controller.

Thank's so much in advance!!

Ivan Lencina
  • 1,787
  • 1
  • 14
  • 25

1 Answers1

14

I solved it using: (ngModelChange) instead of (ionChange)

Ivan Lencina
  • 1,787
  • 1
  • 14
  • 25