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
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>
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
};
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})
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
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
}
}