1

I'm using vuejs with bootstrap-vue. I have two components. A list of objects, and my modal. I open my modal when I click on a particular button. Typically, my modal asks : "Are you sure you want to delete these records ?" for instance.

Everything works fine but I don't know how to retrieve the result of the modal in my parent component (if I clicked on 'ok', or 'cancel',...).

How should I do it ?

Since my modal is opened this way :

In my parent component (the list) :

deleteSelectedGroups () {
  const modalOptions = {
    action: 'delete',
    records: this.selectedGroups,
    recordFields: ['name', 'usersCount'],
    okTitle: 'Delete',
    okVariant: 'danger'
  }
  this.showModalConfirmation(modalOptions)
  // ...
  // if result of modal is true then ...
},

showModalConfirmation (modalOptions) {
  this.$refs.ModalConfirmation.show(modalOptions)
}

In my modal component :

show (modalOptions) {
  for (let option in modalOptions) {
    this[option] = modalOptions[option]
  }
  this.$bvModal.show('modalConfirmation')
}

Should I do it simply by returning the value with my methods ?

Or should I do the vuejs way and emit a variable to the parent ?

EDIT : How I'd like my flow to be (pseudo-code) :

deleteselectedGroups () {
  openModal()
  modalAnswer = modal.getAnswer()
  if (modalAnswer === 'OK') {
    deleteMyRecords() 
  }
}
lbris
  • 1,068
  • 11
  • 34
  • Sounds like what you want is a [Message Box](https://bootstrap-vue.js.org/docs/components/modal/#ok-message-box) which returns a promise once closed with the result. – Hiws Mar 05 '20 at 13:00
  • Yes sort of. The difference is that my modal is custom one (in its own component). And I don't know how to retrieve the value of it. If I click on "ok", then my method would continue and in my example, it would delete selected records. If I click cancel, then it leaves the modal and it does nothing. In the link you gave (which I already had opened in my browser), he does `.then(...)` and he uses the value of the modal. – lbris Mar 05 '20 at 13:28
  • I just noticed i linked the wrong section, I meant to link the [Confirm Box.](https://bootstrap-vue.js.org/docs/components/modal/#confirm-message-box) Here it runs the `then` part once the modal is closed and the value it is passed is whether the `ok` button was clicked or not. So you could `msgBoxConfirm.then(value => { if(value == true) { deleteRecords() } })` – Hiws Mar 05 '20 at 13:36
  • If you want to use your own component, you can listen on the `@ok` event in your parent and run your `deleteRecords` method then. – Hiws Mar 05 '20 at 13:38
  • Yes that's what I want to do. But `@ok` events are usually defined on template elements. Is it possible to do it in a method ? Precisely the one in which I open the modal – lbris Mar 05 '20 at 13:42
  • I'm confused why it NEEDS to be done in the same method. Could you elaborate why? – Hiws Mar 05 '20 at 13:45
  • I edited my post with a pseudo-code part which explains how I imagined it. – lbris Mar 05 '20 at 13:49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/209087/discussion-between-hiws-and-lbris). – Hiws Mar 05 '20 at 13:51

2 Answers2

5

So i ended up making 3 different ways of accomplishing this.

Using MsgConfirmBox's built in promise https://codesandbox.io/s/modal-send-answer-to-parent-3vbiv

This method uses the already built-in Confirm MessageBox which returns a promise that return whether the OK button was clicked or not, when resolved.

Emitting from the child to the parent: https://codesandbox.io/s/modal-send-answer-to-parent-3olms

This method $emit's a custom event to the parent, which can then be used to run a desired method. It can also pass up data to the parent, like a specific item to delete like in the codesandbox.

Implementing own promise: https://codesandbox.io/s/modal-send-answer-to-parent-py3nm

This implements a promise in our custom modal component, to gain similar behavior to the MsgConfirmBox that Bootstrap-Vue has. I personally think this method is a bit "sketchy", as you'll have to do more error handling for various scenarios to resolve/reject the promise properly.

Hiws
  • 8,230
  • 1
  • 19
  • 36
  • Thank you for your time, help and discussion. It was helpful ! For the 3rd solution (promise one) it is said in the docs to always use a `.catch` statement to handle errors. Maybe it is enough to handle errors. I precise that since it is the closest solution to what I wanted to achieve. – lbris Mar 05 '20 at 14:39
1

It's good to create a separate component for modal and emit an event from there as per the vuejs guide So your code will look clean and you will get your value.

Jay Dadhaniya
  • 171
  • 4
  • 15
  • Okay then just emit an event. – Jay Dadhaniya Mar 05 '20 at 12:35
  • Okay but, It seems events are written on template elements (with `@`) ? What I want is the result (programmatically) of my modal but in the method from which I opened it. So I open it in method `deleteSelectedGroups()` and I want the value of the modal closure event in it. So that I can do something like : if 'ok' or if 'cancel' .... How can I do that ? – lbris Mar 05 '20 at 12:44
  • Can you please provide an example in https://codesandbox.io/s/white-tdd-x8uer so I get a better idea about it. – Jay Dadhaniya Mar 05 '20 at 12:58
  • I provided a [part of it](https://codesandbox.io/s/modal-send-answer-to-parent-lsc5v) (just useful pieces with comments in the deleteGroup() method) – lbris Mar 05 '20 at 13:34
  • @lbris https://codesandbox.io/s/modal-send-answer-to-parent-3vbiv Here's a fork of your example using `msgBoxConfirm` – Hiws Mar 05 '20 at 13:41
  • @Hiws Yes that's what I want to do and I already saw that in the docs. But I really need the result of my custom modal that is in a child component, because I display a summary of selected rows to delete in the modal (for example) and do some more customization in the modal that isn't possible with a `msgBoxConfirm`. So since I use a custom template for my modal, the `msgBoxConfirm` isn't possible for me. – lbris Mar 05 '20 at 13:46
  • @ibris Here is solution https://codesandbox.io/s/modal-send-answer-to-parent-57y7c – Jay Dadhaniya Mar 06 '20 at 05:40