Meteor.call don't work inside sweetalert confirmation box

435 views Asked by At

I've got an event to delete intern messages in my app : a button in front, with a click event who call a method. Everything works fine.

But before the call of the method, I'd like a confirm box "Are you sure you want to delete this message ?"

With the standard confirm js function, works fine. But the standard js confirmbox... No styling allowed.

So my idea was to use sweetalert : everything go well, the berts notifications as well, but no message is deleted..

Below my event, confirm box version & sweetalert version, and the method.

Thanks!

confirm box version

Template.Users.events({
    'click .toggle-admin': function() {
        Meteor.call('toggleAdmin', this._id);
    },
    'click button.delete-message':function() {
        if(confirm('Are you sure?')) {
            Meteor.call('deleteMessage', this._id, function(error) {
                if(error) {
                    Bert.alert({
                        title: 'Error',
                        message: error.reason,
                        type: 'danger'
                    });
                } else {
                    Bert.alert({
                        title: 'Success',
                        message: 'Message deleted.',
                        type: 'success'
                    });
                }
            });
        }
    }
});

sweetalert version

Template.Users.events({
    'click .toggle-admin': function() {
        Meteor.call('toggleAdmin', this._id);
    },
    'click button.delete-message':function() {
        swal({
          title: "Are you sure?",
          text: "You will not be able to recover this message!",
          type: "warning",
          showCancelButton: true,
          confirmButtonColor: "#DD6B55",
          confirmButtonText: "Yes, delete it!"
        }).then(function (){
            Meteor.call('deleteMessage', this._id, function(error) {
                if(error) {
                    Bert.alert({
                        title: 'Error',
                        message: error.reason,
                        type: 'danger'
                    });
                } else {
                    Bert.alert({
                        title: 'Success',
                        message: 'Message deleted.',
                        type: 'success'
                    });
                }
            });
        })
    }
});

method

Meteor.methods({
    insertMessage: function(message) {
        ContactMessages.insert(message);
    },
    deleteMessage: function(messageId) {
        ContactMessages.remove({_id: messageId});
    }
});
1

There are 1 answers

1
MasterAM On BEST ANSWER

The native window.confirm() is synchronous, and blocks the JS thread of execution. This means that once the user responds to the prompt, a value is returned by it and execution continues from that point. That is the reason you can use this._id successfully.

With an asynchronous API such as swal2's, which uses promises, you pass a function to handle it once it is resolved or rejected (what you pass to then). In those callbacks, this no longer points to the original object, so you need to preserve access to it (or to other required data) by using a closure or by lexically binding it with an arrow function.

Using a closure:

Template.Users.events({
  'click button.delete-message'() {
    const id = this._id;
    swal({
        // ...
    }).then(function (){ // `id` is available from external function
      Meteor.call('deleteMessage', id, function(error) {
        // ...
      });
    })
  }
});

lexical scope binding using an arrow function:

Template.Users.events({
  'click button.delete-message'() {
    swal({
        // ...
    }).then(() => { //bound to the current `this`
      Meteor.call('deleteMessage', this._id, function(error) {
        // ...
      });
    })
  }
});