Vuex mapActions: mapper parameter must be either an Array or an Object - vue.js

When I'm trying to use the "getProducts" method through mapActions i am getting the "this.getProducts" is not a function.
Basically i get the actions from my product.js. So i don't know really why the error is existing.
I hope u can help me to handle with it. :)
My component ProductList.vue:
<script>
import ProductCard from "./ProductCard.vue";
import { mapState, mapActions } from "vuex";
export default {
components: {
ProductCard
},
computed: {
//state.modulname.state.js(products state)
...mapState("product" ["products"])
},
mounted() {
this.getProducts();
},
methods: {
...mapActions("product"["getProducts"])
}
};
</script>
<style>
</style>
My product.js File:
import store from "../../store/store";
import Product from "../../apis/Product";
const state = {
product: null,
products: [],
};
const mutations = {
SET_PRODUCT(state, product) {
state.product = product;
},
SET_PRODUCTS(state, products) {
state.products = products;
},
};
const actions = {
getProduct({ commit }, productId) {
Product.show(productId).then((response) => {
commit("SET_PRODUCT", response.data);
});
},
getProducts({ commit }) {
Product.all().then((response) => {
commit("SET_PRODUCTS", response.data);
});
},
};
const getters = {
getProductID() {
return (id) => state.products.filter((product) => product.id === id);
},
};
export default {
namespaced: true,
store,
state,
mutations,
actions,
getters,
};

Try this:
...mapActions([
'product/getProducts'
])

Related

How can I delete an object from getter if PersistedState is used

I am creating a small website and faced with such a problem. On the site, I use PersistedState to save the products that I added to favorites. But the problem is that I can't delete this product since splice doesn't work. He only visually removes it, but it can be seen from VueJS DevTools that it is still there.
store.js
import { createStore } from 'vuex'
import axios from "axios"
import createPersistedState from "vuex-persistedstate";
export default createStore({
state: {
products: [],
favourites: []
},
getters: {
PRODUCTS(state){
return state.products
},
PRODUCT_BY_ID(state){
return ProductId => {
return state.products.find(Product => Product.id === ProductId)
}
},
FAVOURITES(state){
return state.favourites
}
},
mutations: {
SET_PRODUCTS_TO_STATE: (state, products) =>{
state.products = products
},
SET_TO_FAVOURITES: ( state, favouritesItem) =>{
if (state.favourites.length){
let ProductExist = false
state.favourites.map(function(item){
if (item.id === favouritesItem.id){
ProductExist = true
}
})
if (!ProductExist){
state.favourites.push(favouritesItem)
}
} else{
state.favourites.push(favouritesItem)
}
}
},
actions: {
async GET_PRODCUTS_FROM_DB({commit}){
try {
const products = await axios("http://localhost:3000/products", {
method: "GET"
})
commit("SET_PRODUCTS_TO_STATE", products.data)
return products.data
} catch (error) {
return error
}
},
ADD_TO_FAVOURITES({commit}, favouritesItem){
commit('SET_TO_FAVOURITES', favouritesItem)
}
},
modules: {
},
plugins: [
createPersistedState()
]
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
products-item.js
<script>
import { mapGetters } from 'vuex'
export default {
name: "ProductsCart",
data(){
return {
IsProductExist: false
}
},
computed: {
...mapGetters([
'FAVOURITES'
]),
},
props: {
Productsitem: {
type: Object,
default() {
return {}
}
}
},
methods: {
addToCarts(){
if(this.$route.name === 'Favourites'){
this.FAVOURITES.splice(this.FAVOURITES.indexOf(this.Productsitem), 1)
} else {
this.$emit('addToCarts', this.Productsitem)
this.IsProductExist = true
}
}
},
mounted(){
this.$nextTick(function () {
if(this.FAVOURITES.length > 0){
for(let i = 0; i < this.FAVOURITES.length; i++){
if(this.FAVOURITES[i].id === this.Productsitem.id){
this.IsProductExist = true
}
}
}
})
}
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
I have found a solution to my problem. In mutation, as #yoduh said above, it was necessary to correctly refer to getter in mutations. Now the mutation looks like this:
DELTE_PRODUCTS(state, {data, getters}){
getters.FAVOURITES.splice(0,1)
//console.log(data);
//console.log(state);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

On component created hook call Action to fetch data from database and store it in state and then call Getter to get the data

So basically I have this component and I am using its created hook to fetch data using vue-resource and VUEX action, storing that data in store and right after that trying to get that data using VUEX getter but I am unable to do so. Any work around or I am doing something wrong. I am new to Vue!
Component:
import { mapActions } from 'vuex';
import { mapGetters } from 'vuex';
export default {
components: {
categoryHeader: CategoryHeader,
categoryFooter: CategoryFooter,
AddCategory
},
data() {
return {
openCatAdd: false,
categories: [],
pagination: []
}
},
methods: {
...mapActions([
'getCategories'
]),
...mapGetters([
'allCategories'
])
},
created() {
this.getCategories(1);
this.categories = this.allCategories();
// console.log(this.categories);
}
};
Store:
import Vue from "vue";
const state = {
categories: [],
};
const mutations = {
setCategories: (state, payload) => {
state.categories = payload;
}
};
const actions = {
getCategories: ({commit}, payload) => {
Vue.http.get('categories?page='+payload)
.then(response => {
return response.json();
})
.then(data => {
commit('setCategories', data.data);
}, error => {
console.log(error);
})
}
}
const getters = {
allCategories: state => {
console.log(state.categories);
return state.categories;
}
};
export default {
state,
mutations,
actions,
getters
};

vuex: unknown getter: articles

I try to implement vuex modules and understand usage. While trying to import modules in my home.vue, I have found this solution:
import { FETCH_INDEX_ARTICLES } from "#/store/types/actions.type.js";
// imports this => export const FETCH_INDEX_ARTICLES = "fetchIndexArticles"
import { mapGetters, mapActions} from 'vuex'
export default {
name: "Home",
data() {
return {}
},
computed: {
...mapGetters(['articles']),
},
methods: {
...mapActions([FETCH_INDEX_ARTICLES])
}
created() {
this.$store.dispatch(FETCH_INDEX_ARTICLES);
}
};
but instead I get
vuex.esm.js?2f62:438 [vuex] unknown action type: fetchIndexArticles
vuex.esm.js?2f62:950 [vuex] unknown getter: articles
store/index.js
export default new Vuex.Store({
modules: {
articles,
}
});
store/modules/articles.js
const state = {
articles: [],
};
const getters = {
articles(state) {
return state.articles;
},
};
const mutations = {
[SET_ARTICLES] (state, pArticles) {
state.article = pArticles
state.errors = {}
}
}
const actions = {
[FETCH_INDEX_ARTICLES] (context) {
context.commit(FETCH_START)
return ApiService
.get('/articlelist/index/')
.then((data) => {
context.commit(SET_ARTICLES, data.articles);
context.commit(FETCH_END)
})
.catch((response) => {
context.commit(SET_ERROR, response.data.errors);
})
}
};
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
How can I correctly import vuex module?
Thanks
You must specify your modules,
Your way is valid when you import your modules directly into your component
...mapGetters('articles', {
article: 'articles',
})
this.article(2)
https://vuex.vuejs.org/guide/modules.html#binding-helpers-with-namespace
To facilitate the use I use the method dispatch for actions
this.$store.dispatch('articles/FETCH_INDEX_ARTICLES', {anydata})

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

Pre-fetch data using vuex and vue-resource

I'm building an app following this structure: http://vuex.vuejs.org/en/structure.html
My components/App.vue like this:
<template>
<div id="app">
<course :courses="courses"></course>
</div>
</template>
<script>
import Course from './course.vue'
import { addCourses } from '../vuex/actions'
export default {
vuex: {
getters: {
courses: state => state.courses,
},
actions: {
addCourses,
}
},
ready() {
this.addCourses(this.fetchCourses())
},
components: { Course },
methods: {
fetchCourses() {
// what do I have to do here
}
}
}
</script>
How can I fetch the data and set it to the state.courses ?
Thanks
I've just figured it out:
in /components/App.vue ready function, I just call:
ready() {
this.addCourses()
},
in vuex/actions.js:
import Vue from 'vue'
export const addCourses = ({ dispatch }) => {
Vue.http.get('/api/v1/courses')
.then(response => {
let courses = response.json()
courses.map(course => {
course.checked = false
return course
})
dispatch('ADD_COURSES', courses)
})
}
and in vuex/store.js:
const mutations = {
ADD_COURSES (state, courses) {
state.courses = courses
}
}