'How to handle navigation when removing the current page's Vuex record?
I have a ClientManagePage where I display client information and allow for the removal of the displayed client.
The vue-router route configuration for that page looks like this:
{
path: '/client/:id/manage',
name: 'client',
component: ClientManagePage,
props: ({ params }) => ({ id: params.id }),
}
The client entities are stored in a vuex store. ClientManagePage gets its client entity from the store using the id prop and displays various properties of the client and a "remove" button.
The remove button listener is (inside a mapActions):
async removeClientClicked(dispatch) {
// Wait for the action to complete before navigating to the client list
// because otherwise the ClientListPage might fetch the client list before
// this client is actually deleted on the backend and display it again.
await dispatch('removeClientAction', this.id);
this.$router.push({ name: 'clientList' });
},
The vuex action that removes a client is:
async function removeClientAction({ commit }, id) {
// Remove the client from the store first (optimistic removal)
commit('removeClient', id);
// Actually remove the client on the backend
await api.remove('clients', id);
// Moving "commit('removeClient', id);" here still produces the warning mentioned below
}
My problem is how to handle navigating to the other route when removing a client. The current code produces warnings in development mode such as:
[Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined"
found in
---> <ClientManagePage> at src/pages/ClientManagePage.vue
<Root>
This is of course caused by the reactivity system kicking in and trying to update the content of the page with the now-deleted vuex client entity. This happens before the removeClientAction is completed therefore the navigation to the ClientList page.
I've come up with some possible solutions to this, but they are not very appealing:
- Have a
v-if="client"at the top of the ClientManagePage that hides everything while the client does not exist in the store. - Use the computed property
clientin ClientManagePage to return a default "dummy" client that contains the required properties for the page. The page will still flash with "fake" content while the action is underway though. - Navigate to "clientList" right after (or even before) dispatching
removeClientAction. This causes the clientList to display the removed client briefly while the action completes which is not good.
Are there other solutions to this seemingly common problem of navigating away when deleting the underlying vuex entity displayed on the current page?
Solution 1:[1]
One option is to externalize the deletion of the record. There are a number of ways to do that, but the simplest for me was to create a new route, /records/delete/:id, and place a route guard on that route that triggers the removal. Then redirect to the records list where you wanted to go in the first place. Something along the lines of:
import store from "wherever/your/store/is";
const routes = [{
path: "/records/delete/:id",
name: "deleteRecord",
props: true,
beforeEnter: (to, from, next) => {
store.dispatch("DELETE_RECORD", to.params.id).then(() => console.log("record deleted!"));
next({name: "some/path/you/wanted/to/go/to"});
}
}, ...];
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Celos |
