1

I'm trying to implement a messaging/alerting system through Vuex and from the various components on a click method - for example - pass an argument that tells vuex getter which message to display. Except that it is not returning the any data.

I know this may be overkill just for a simple flash messaging system, but it server a greater purpose once I get it working properly.

At the moment, I am passing the message key/name for matching in the state alertMessages array via the Alert component, but eventually this would be passed from the Login Component upon a method call.

Structure:

• App.vue
--> • Alert component
--> • Login component (login method)
--> • NavHeader component
    --> Logout Btn (logout method)
• Store.js

Here's what I have: Store.js:

export const store = new Vuex.Store({
   state: {
      alertMessages: [
         { key: "loginSuccess", alert: "logged in.", redirectPath: "dashboard" },
         { key: "loginError", alert: "try again.", redirectPath: "login" }
      ]
   },
   getters: {
      pickMessage: state => {
         return (something) => {
            state.alertMessages.forEach(msg => {
               if(msg.key == something){
                  // This return does not send any data through.
                  return msg.alert;
               }
            });
            // This return works. Alert gets Hey There.
            // return "Hey There";
         }
      }
   }
});

Alert.vue: Template

<template>
   <div class="alert">
       {{message}}
   </div>
</template>

Scripts

export default {
   name: 'alert',
   data () {
      return {
         message: ''
      }
   },
   computed: {
      alertMessage: async function(){
         try {
            // Passing loginSuccess for key matching.
            this.message = this.$store.getters.pickMessage('loginSuccess');
         } catch(error) {
            console.log(error);
         } finally {

         }
      }
   },
   created: function(){
      this.alertMessage;
   }
}

Seems the if() statement is doing something that prevents the return inside it to work. I know that the function argument from the Alert component is getting passed, because I can console log it. What am I missing here?

Thanks so much in advance,

Sergio

1
  • computed methods don't work with async, unless you have a plugin installed for that Commented Feb 1, 2018 at 18:07

2 Answers 2

1

As per MDN the only way to terminate a forEach() loop is to throw exception. So there is no other way to terminate a forEach() loop that's the problem in your code above.

Sign up to request clarification or add additional context in comments.

2 Comments

Aahhh... so to clean up the working code, I should be using a for of loop instead?
Yeah using a plain loop is the solution in your case.
1

So, changing the getters to the code below worked... Why exactly was making my initial code not work? Because the return was inside the forEach loop (multiple returns)?

Working code:

   getters: {
      pickMessage: state => {
         return (something) => {
          let val;
            state.alertMessages.forEach(msg => {
               if(msg.key == something){
                 val = msg.alert;
               }
            });
            // This return works. Alert gets Hey There.
            // return "Hey There";

            return val;
         }
      }
   }

EDIT: An even cleaner solution is to replace the forEach loop with a for...of loop – Thanks Ujjwal Nepal!!!

Here is the code example:

getters: {
      pickMessage: state => {
         return (something) => {
            let arr = state.alertMessages
            for(let a of arr){
               if(a.key == something){
                  return a.alert;
               }
            }
         }
      }
   }

1 Comment

This is exactly what utility libraries like lodash try to tackle. const result = _.find(state.alertMessages, { key: something }); return _.get(result, 'alert');. The second line is only necessary in case no alert messages were found - it handles the case where result is undefined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.