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:
- Button: activate a method inside the component;
- Method: activate an action from store;
- Action: it uses a external API;
- 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();
}
}