harmyderoman/vuejs-confirm-dialog

Modal persists if hardware back button is pressed

Closed this issue · 5 comments

Hi,

I've created a modal setup using this library. It's been working great, but when I press the browser back button, the modal persists. I would like it to be inactive again if I press the back button.

After searching, I did come across this useful answer on using the query param. I was wondering if there was a a way to translate this behavior to this library. For my current use case, I would like to provide a one-time code to the modal, and that code should go away if I press the browser back button or refresh the page (it works for the latter, but not the former).

Please let me know if there's a way to do so, or if it's something that you would be able to develop in the future.

There are a few ways to solve this issue. If you are using Vue Router the easiest one will be adding this code to your modal component:

	import { watch } from 'vue'
	import { useRoute } from 'vue-router'

	const route = useRoute()

	watch(route, () => {
	  emit('cancel')
	})

So if the route changes modal will close itself

Thanks for the suggestion! I gave it a try and it's hiding the modal now when pressing the back button.

In my unit tests, I am getting the following error:

[Vue warn]: Invalid watch source: undefined A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.

I have the following code when unit testing. Note that I am using mount because there is a child component and I want to test the behavior of that as well.

mount(ConfirmationDialog, {
    props: {
      prop1: value1
    },
    plugins: [createTestingPinia({stubActions: false})]
  });

Do I need something additional to address the console warning? Any chance it is giving this warning because it thinks watching route is an antipattern?

route is a reactive object, so watching it is okay. I don't get any warnings when I use it.
But in unit tests is different. Unit test doesn't use browser runtime it uses Node.js runtime and doesn't really have browser history.
So this may cause a problem. Look here to learn how to implement router in unit tests.

Also, you can try this approach:

	import { watch, toRefs } from 'vue'
	import { useRoute } from 'vue-router'

	const router = useRoute()
	const { path } = toRefs(router)

	watch(path, () => {
		emit('cancel')
	})

Here we obviously declare the watching object as ref, so it's clearly reactive

I am getting the same warning when running unit tests, so I may need to take another look there.

I think for runtime purposes this solution works well, though. Thanks for the help!