Skip to content

Instantly share code, notes, and snippets.

@NicolasDurant
Last active September 2, 2022 08:34
Show Gist options
  • Save NicolasDurant/98ebffb20c10cb124e8bb743308599a7 to your computer and use it in GitHub Desktop.
Save NicolasDurant/98ebffb20c10cb124e8bb743308599a7 to your computer and use it in GitHub Desktop.
[Vue / Vuex / Nuxt - Request Error Handling Store + Example] A Notification Component that lets an v-alert pop up when a request fails. It is connected with the Vuex notification.js store. The Vue Components in this example use the vue-decorators. But this would obviously also work with normal Vue-Components. #JavaScript #VueJS #NuxtJS #Vuex #Er…
/**
* Fetching the issues via the Invoicing service and saving them in our store state: issuesAll.
*/
fetchIssues ({ dispatch }, params) {
return Invoicing.fetchIssues(params)
.then((response) => {
dispatch('setIssuesAll', response.data)
dispatch('sortIssues', response.data)
})
.catch((error) => {
const notification = {
error,
message: 'Oops, something went wrong fetching the issues'
}
dispatch('notification/generateNotification', notification, { root: true })
})
},
/** Store that helps displaying notifications to the user.
* This is not only for request error handling but also for success alerts.
* @author Nicolas Durant
*/
export const state = () => ({
notifications: []
})
export const mutations = {
ADD_NEW_NOTIFICATION (state, notification) {
state.notifications.push(notification)
},
REMOVE_NOTIFICATION (state, notification) {
const not = state.notifications.filter(item => item !== notification)
state.notifications = not
}
}
export const actions = {
/**
* Adds a temporary notification that gets displayed to the user.
* Automatic removal after 3s.
* @param {object} notification - consists of type, message
*/
async addNewNotification (context, notification) {
context.commit('ADD_NEW_NOTIFICATION', notification)
await setTimeout(() => {
context.commit('REMOVE_NOTIFICATION', notification)
}, 3000)
},
/**
* Helper function to generate a notification.
* @param {object} error
* @param {string} message
* @param {string} type - regulates the kind of alert that gets displayed
*/
generateNotification ({ dispatch }, payload) {
const notification = {
error: payload.error ? payload.error : null,
type: payload.type ? payload.type : 'error',
message: payload.message
}
dispatch('addNewNotification', notification)
throw payload.error
},
/**
* Removes the provided notification from the Array of notifications.
* @param {object} notification - consists of type, message
*/
removeNotifications (context, notification) {
context.commit('REMOVE_NOTIFICATION', notification)
}
}
export const getters = {
getNotifications (state) {
return state.notifications
}
}
<template>
<div class="container-style">
<v-alert
:type="notification.type"
v-for="(notification,index) in notifications"
:key="index"
class="alert-style"
elevation="3"
dismissible
dense
>
<span v-if="notification.message">
{{ notification.message }}<br>
</span>
<span v-if="notification.error">
{{ notification.error }}
</span>
</v-alert>
</div>
</template>
<script>
import { Component, Vue } from 'vue-property-decorator'
import { namespace } from 'vuex-class'
/** Component representing our Error, Success, Info & Warning messages.
* It communicates with the according notification Vuex Store, and displays messages that get add to the notif. array.
* @author Nicolas Durant
* @memberof default layout - so we can show messages whenever
* @requires vue-property-decorator - for component decoration
* @requires namespace vuex-class - for accessing the invoicing store module
*/
/**
* Namespacing the Notification store module to access it with @-Decorator.
*/
const notification = namespace('notification')
@Component({})
export default class TheNotification extends Vue {
/**
* Mapping the store functionalities to local methods/variables to access them with 'this'.
*/
@notification.Getter('getNotifications') notifications
}
</script>
<style lang="scss" scoped>
.alert-style{
width: 500px;
}
.container-style{
max-height: 200px;
position: fixed;
overflow: hidden;
top: 90%;
left: calc(50% - 250px);
z-index: 2;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment