Home > OS >  activate a modal from a store of Nuxt 2 (vuejs)
activate a modal from a store of Nuxt 2 (vuejs)

Time:01-10

I need to activate a modal component from vuex store. I was using 'this.$refs['modalSuccess'].show()' to show the modal inside the component when the result API was successed!

But I needed to change the function 'sendLeadResponse' from methods (component) to action (store). After that, I cannot activate the modal anymore with this 'this.$refs['modalSuccess'].show()'.

Is there any way to call it from a store?

This is the following flow:

  1. Button: activate a method inside the component;
  2. Method: activate an action from store;
  3. Action: it uses a external API;
  4. Modal: If the result is ok it activates a modal which it is inside the component;

COMPONENT WITH BUTTON AND THE MODAL

<template>
    <section>
    <div >
        <SmallButton 
            smallButtonText="Quero ser cliente →"
            @event="createLeadObject()"
            id="show-btn"
        />
    </div>
        <b-modal 
            ref="modalSuccess" 
            ok-only
        > Obrigado pelo interesse! Em breve entraremos em contato. 
        </b-modal>
    </div>
    </section>
</template>

<script>
import SmallButton from '../SmallButton.vue'
export default {
    name: 'BeClientForm',
    components: {
        SmallButton
    },
    methods: {
        createLeadObject(){
            const dataLeadObject = {
                date: new Date(),
                fullName: this.lead.name,
                email: this.lead.email,
                phone: this.lead.phone,
                comment: this.lead.comment
            }
            this.$store.dispatch('sendLeadResponse', dataLeadObject)
        },
    }
}
</script>

ACTION FROM STORE

actions: {
        async sendLeadResponse({commit}, dataLeadObject){
            const jsonDataObject = JSON.stringify(dataLeadObject)
            
           await fetch("http://localhost:5000/api/lead/leadResponse", {
                method: "POST",
                headers: {"Content-type": "application/json"},
                body: jsonDataObject
            })
            .then((resp) => resp.json())
            .then((data) => {
                if (data.error) { 
                    commit('MESSAGE_RESPONSE', data.error)
                }
                else {
                    commit('RESET_LEAD_RESPONSE')
                    !!!!!!!!!!!!! this.$refs['modalSuccess'].show() !!!!!!!!!!!!!! [it is not working)
                }
            })
        },
    }

CodePudding user response:

The Vuex store is designed to only care about the state. It does not have direct access to your components or this.$refs. What you can do is set a piece of state in your store based on the result of your fetch and have your component access that state, and/or return a promise from your action so the result is handed directly back to your component

async sendLeadResponse({ commit }, dataLeadObject) {
  const jsonDataObject = JSON.stringify(dataLeadObject);

  // assign promise from fetch
  const response = await fetch('http://localhost:5000/api/lead/leadResponse', {
    method: 'POST',
    headers: { 'Content-type': 'application/json' },
    body: jsonDataObject
  })
    .then(resp => resp.json())
    .then(data => {
      if (data.error) {
        commit('MESSAGE_RESPONSE', data.error);
        // promise to resolve to false
        return false;
      } else {
        commit('RESET_LEAD_RESPONSE');
        // promise to resolve to true
        return true;
      }
    });
  
  // return promise
  return response
},
// change to async
async createLeadObject() {
  const dataLeadObject = {
    date: new Date(),
    fullName: this.lead.name,
    email: this.lead.email,
    phone: this.lead.phone,
    comment: this.lead.comment
  };
  const response = await this.$store.dispatch('sendLeadResponse', dataLeadObject);
  // if response is 'true', show modal
  if (response) {
     this.$refs['modalSuccess'].show();
  }
}
  • Related