Nuxt.js and Vuex – dumping flash messages

Context:

  • A child component has received an error message, and needs to communicate it to the parent layout.
  • There’s no unhacky way to do that, so we should put it in the application store (vuex).
  • When the user navigates, the error is retained forever more.

It’s a problem seemingly without a clean answer.

Step 1: In the vuex store, create an errors array to hold the errors. Create two mutations: ‘set_errors’ and ‘clear_errors’.

// store/index.js
export const state = () => ({
  errors: []
})

export const mutations = {
  errors (state, errors) {
    state.errors = errors
  },
  clear_errors (state) {
    state.errors = []
  }
}

Step 2: In the component generating the error, put the errors in the vuex store.

// sign in has failed.
.catch(e => {
        let errors
        switch (e.response.status) {
          case 422:
            errors = this.translateErrors(e.response.data.errors)
            this.$store.commit('set_errors', errors)
            break
        }
      })

Step 3: In the ‘Errors’ component that lives in the layout, capture and display the errors. Confirm these two pieces are communicating.

// components/Errors.vue

<template>
    <div>
      {{errors.map(e => e)}}
    </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  computed: mapState(['errors'])
}
</script>

If that’s all working, it’s time to clear the message between navigation events.

Step 4: Create a ‘clearFlash’ middleware.

// middleware/clearFlash.js

export default function (context) {
  if (context.store.state.errors.length > 0) {
    context.store.commit('clear_errors')
  }
}

Step 5: Wire up the middleware in nuxt.config.js. Add the router and middleware keys if needed.

//nuxt.config.js

  router: {
    middleware: 'clearFlash'
  },

All done and working!