Action is not defined as a method in the component vue.js - vue.js

I'm trying to access an action as a method in component, But got error of
this.delete_notifaction is not a function
notifaction.js
export const actions = {
add_notifaction({ commit }, notifaction) {
commit("ADD_NOTIFACTION", notifaction);
},
delete_notifaction({ commit }, notificationToRemove) {
commit('DELETE_NOTIFACTION', notificationToRemove)
}
};
store/index.js
modules : {
notifaction
},
Component.vue
methods: mapActions('notifaction',["delete_notifaction"]),
mounted() {
this.delete_notifaction(this.notification);
}
Any Help?

Try this
methods: {
...mapActions(['delete_notifaction']),
}
See here for spread syntax
https://stackoverflow.com/a/48137766/10118668

Related

How to trigger a Vue method when computed property changes

Essentially, in a Vue application, I have a page that lists Contacts. And a search form that is part of a header component. I capture the input search term as a state variable in the vuex store and track it as a computed variable.
I have a method to retrieve contacts that is called within the mounted hook. I want to call the same getContacts method again whenever the state search variable changes. Using a watcher to do this atm, but I have read that watching a computed value is not the right way. Wondering if there is a better way to do this. Script below.
<script>
import API from '#/utils/Api.js'
...
export default ({
...
tableData: [],
}
},
computed: {
search() {
return this.$store.getters.search;
}
},
mounted() {
this.getContacts();
},
methods: {
async getContacts() {
try {
const {data} = await API.get('/contacts?search=' + this.search)
this.tableData = data
} catch (e) {
console.error(e)
}
}
},
watch: {
search () {
this.getContacts();
}
}
})
</script>
Try to watch directly the state item and then pass the new value as parameter for the method, then use immediate:true to replace the mounted hook call :
export default ({
...
tableData: [],
}
},
methods: {
async getContacts(val) {
try {
const {data} = await API.get('/contacts?search=' + val)
this.tableData = data
} catch (e) {
console.error(e)
}
}
},
watch: {
'$store.getters.search': {
handler(newVal)
this.getContacts(newVal);
},
immediate:true
}
}
})

How to use this data from Vuex inside the component?

What is the best way to use this data from the Vuex store's Action in the needed component?
import axios from 'axios'
export default {
namespaced: true,
state: {
items: []
},
actions: {
fetchCategories ({state, commit}) {
return axios.get('/api/v1/categories')
.then(res => {
const categories = res.data
commit('setItems', {resource: 'categories', items: categories}, {root: true})
return state.items
})
}
}
}
Component
export default {
components: {
ThreadCreateModal,
ThreadList
},
data () {
return {
...
}
},
computed: {
...
},
created () {
...
},
methods: {
...
}
</script>
Where and how should I use that action for binding the data in this component?
Use mapState by import it from vuex and call it in computed:
computed: {
...mapState(['items']), // if you dont use namespace
...mapState("your_module_name", ['items'] ) // if you use namespace
},
then you can access it by this.items.
However, you can access it directly this.$store.state.items

VUEX - Many mapActions with same action name on the same page

I have several differents files for a lot of modules.
Some of the share the same action name
There is some page that use 2 or more mapActions for different modules
On my page is something like this:
methods: {
...mapActions({
documents: ['setDocumentImage'],
documentAddress: ['setDocumentImage'],
selfie: ['setDocumentImage']
}),
}
All my modules have a action setDocumentImage
But the problem is that i have to invoke them like: this.setDocumentImage(file)
Is there a way to create an alias for each one of these mapAction that my page can differentiate?
Or how can I fix it?
Yes there is a way ! Here you are :
methods: {
...mapActions('documents', { setDocumentImage: 'setDocumentImage' }),
...mapActions('documentAddress', { setDocumentAddressImage: 'setDocumentImage' }),
...mapActions('selfie', { setSelfieDocumentImage: 'setDocumentImage' }),
}
You can use namespacing if you are using modules in composing your store.
Something like this:
const moduleA = {
namespaced: true, //namespacing set to true.
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
namespacedModuleA: moduleA,
b: moduleB
}
})
Then in your mapAction you can do this :
methods: {
...mapActions({
actionOfA: ['nameSpacedModuleA/actionOfA'],
actionOfB: ['actionOfB'],
}),
}
If you do not want to use mapActions, you can also do
this.$store.dispatch('nameSpacedModuleA/actionOfA')
More on namespacing with modules here

Global EventBus to pass data between components does not work

I am trying to use a global eventbus in VueJs but have been unsuccessful so far.
I have the following code. When I navigate from ResetPassword to Login screen, I should see the successMessage with a Your password has been changed successfully. Please login to continue but it always shows a blank.
What could I be doing wrong?
plugins.js:
Vue.prototype.$eventHub = new Vue();
ChangePassword.vue:
methods:
{
ChangePassword()
{
this.$eventHub.$emit('navigation-message', 'Your password has been changed successfully. Please login to continue.');
this.$router.push({ name: 'login'});
},
},
Login.vue:
data() {
return {
successMessage:'',
};
},
created ()
{
this.$eventHub.$once('navigation-message', this.successMessage);
},
beforeDestroy()
{
this.$eventHub.$off('navigation-message');
},
Update: 12/8/2019: I changed the login.vue as per comment by #tony19 but the issue still exists.
Login.vue:
created ()
{
this.$eventHub.$once('navigation-message', (payload)=>
{
updateSuccessMessage(payload);
});
},
methods:
{
updateSuccessMessage(payload)
{
this.successMessage=payload;
},
You need to add this.
created () {
this.$eventHub.$on('navigation-message', payload => {
this.updateSuccessMessage(payload)
})
},
methods: {
updateSuccessMessage(payload) {
this.successMessage = payload
}
}
Also make sure you're actually importing plugin.js globally (e.g. inside your main file where you import Vue) and make sure your components have access to it.
Try this:
created() {
console.log(this.$eventHub)
}

Watching vuex state change from vuejs component

I am new to both vue.js and vuex. I have a component that need to dispatch an action when a specific data is available in the state. How can I do this.
Example:
export default {
name: 'MyComponent',
computed: {
targetItem() {
return this.$store.getters.getTarget(this.$route.params.id);
}
}
}
In the example above i would like to dispatch a new action on the store when targetItem has a value. This is so i can trigger an ajax request via a vuex action to collect more data about targetItem
Thanks
I eventually found a solution that work
export default {
name: 'MyComponent',
computed: {
targetItem() {
return this.$store.getters.getTarget(this.$route.params.id);
}
},
watch: {
shop (newVal, oldVal) {
if(!!newVal && !oldVal) {
const {targetItem} = this;
this.$store.dispatch('ACTION_NAME',{targetItem});
}
}
}
}
Thanks