I have this Read.js that reads an image. And I want to save the content of the image (in bytes) into a vuex Store.
I'm trying to import the store into Read.js with:
import Store from "src/store/index";
After I read the bytes, I try to access the actions to save it to the state using:
Store.actions.A_updateImage(payload);
But i get that ".actions" is "Undefined".
This is the main store file that import the modules:
//src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import My_store from './modules/My_store'
Vue.use(Vuex)
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
My_store
},
strict: process.env.DEBUGGING
})
return Store
}
This is the store module that has the action i want to use:
//src/store/modules/My_store.js
const state = {
Image: {}
}
const mutations = {
M_updateImage: (state, Image) => {
state.Image = Image;
},
}
const actions = {
A_updateImage({ commit }, Image) {
commit('M_updateImage', Image)
}
}
const getters = {
getImage:(state) =>{
return state.image
}
}
export default {
namespaced: true,
getters,
mutations,
actions,
state
}
How can I import and call the action I need to use from the Read.js file?
Thank you
Related
I have created a reducer called auth and persisted in this reducer.
I want to get auth value outside of the functional component or class component, for example in the utils. How can I do that?
authAction.js
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LoginSuccess = (payload) => {
return {
type: LOGIN_SUCCESS,
payload
};
};
authReducer.js
import { LOGIN_SUCCESS } from './authAction';
// INITIAL TIMER STATE
const initialState = {
user: {}
};
// Auth REDUCER
export const authReducer = (state = initialState, { type, payload }) => {
switch (type) {
case LOGIN_SUCCESS:
return { ...state, user: payload };
default:
return state;
}
};
persist auth reducer
const reducers = {
auth: authReducer
};
const persistConfig = {
key: 'primary',
storage,
whitelist: ['auth'] // place to select which state you want to persist
};
This is not really "react-redux" way. Your store is a part of react application that is just big react component. However, you can create your store in separate module outside of your application and use it where you want importing instance of your store.
For example, you are creating your store in store.js:
// store.js
export default createStore(reducer, preloadedState, enhancers);
Then, you can import it inside your react application
// app.jsx
import store from '/path/to/store';
import { Provider } from 'react-redux';
function App () {
<Provider store={store}>{everything else}</Provider>
}
and inside your utils
// my-util.js
import store from '/path/to/store';
function util() {
// do whatever you want with same instance of store
// for example, return current state
return store.getState()
}
You can subscribe to store, if you need or just get current state. Or you can do complex stuff with replacing reducers for seamless client side updates.
I wrote the following code but it shows an error. What is the reason for this?
Error
[vuex] unknown action type: showRegisterLogin/show
HomePage.vue // component
When using the sh method This error is caused
import { mapState, mapActions } from "vuex";
export default {
name: "HomePage",
components: {
RegisterLogin
},
data() {
return {}
},
computed: {
...mapState({
showRegisterLogin: state => state.showRegisterLogin.show
}),
},
methods: {
sh() {
this.$store.dispatch('showRegisterLogin/show');
}
}
}
/ store / modules / showRegisterLogin.js
// States
const state = {
show: false,
};
// Getters
const getter = {
show (state) {
return state.show;
}
};
// Mutations
const mutation = {
showPage (state) {
return state.show = true;
},
hidePage (state) {
return state.show = false;
}
};
// Actions
const action = {
show({ commit }) {
commit('showPage');
},
hide({ commit }) {
commit('hidePage');
}
};
export default {
namespaced: true,
state,
getter,
mutation,
action
}
/ store / store.js
'use strict';
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import showRegisterLogin from "./modules/showRegisterLogin";
export default new Vuex.Store({
modules: {
showRegisterLogin,
}
});
I also imported the store.js file into app.js and registered it in new vue
The structure of the store, module, and component are fine, except for the name of the store objects in your module:
getter should be getters
mutation should be mutations
action should be actions
Probably just typos. Those can't be arbitrarily named since Vuex looks specifically for those keys.
I'm trying to split up my Nuxt Vuex store files into separate files. And NOT have all Vuex getters, mutations and actions into one huge file. This demo project is on Github by the way.
I'v read this official Nuxt Vuex Store documentation; but can't seem to get it working. It's a bit vague on where to put stuff.
I have the following in these files:
Below is my: store/index.js
import Vue from "vue";
import Vuex from "vuex";
import Auth from "./modules/auth";
Vue.use(Vuex);
export const store = () => {
return new Vuex.Store({
state: {
},
modules: {
Auth
}
})
}
This is in my: store/auth.js
const state = () => {
username: null
};
const getters = {
username: state => {
return state.username;
},
isAuthenticated: state => {
return state.username != null;
}
};
const mutations = {
login: (vuexContext, username) => {
vuexContext.username = username;
this.$router.push("/dashboard");
},
logout: vuexContext => {
vuexContext.username = null;
this.$router.push("/");
}
};
const actions = {
};
export default {
state,
getters,
mutations,
actions,
};
And finally in my: pages/index.vue
This is where I'm calling that login mutation:
<script>
export default {
layout: "non-logged-in",
data() {
return {
username: null
}
},
methods: {
onSubmit() {
this.$store.commit("login", this.username);
}
}
}
</script>
The error I'm getting:
[vuex] unknown mutation type: login
What am I doing wrong here? I thought i'm importing all the stuff correctly in the store/index.js
You have to export your store constant like this inside your store/index.js file:
export default store
Put this code line at the end of your file.
So as #jeremy.raza described this is what I changed in order to get it working:
store/index.js
import Vue from "vue";
import Vuex from "vuex";
import Auth from "./modules/auth";
Vue.use(Vuex)
const store = () => {
return new Vuex.Store({
state: {
},
modules: {
Auth
}
})
}
export default store;
Changes in the store/auth.js
Note the changes in how I wrote the state, getters and mutations method notation.
const state = () => ({
username: null
});
const getters = {
username(state) {
return state.username;
},
isAuthenticated(state) {
return state.username != null;
}
};
const mutations = {
login(vuexContext, username) {
vuexContext.username = username;
this.$router.push("/dashboard");
},
logout(vuexContext) {
vuexContext.username = null;
this.$router.push("/");
}
};
const actions = {
};
export default {
state,
getters,
mutations,
actions,
};
I'm a little bit confused with vuex store component.
How should I obtain state of another module?
I tried a different ways to get data from store and always got Observer object. What is the correct way to knock knock to observer?
If I try to get anything from this object directly, like rootState.user.someVariable then I got undefined response.
Don't have a problem getting state from components.
Edit. Add code
User module
import * as Constants from './../../constants/constants'
import * as types from '../mutation-types'
import axios from 'axios'
const state = { user: [] }
const getters = {
getUser: state => state.user
}
const actions = {
getUserAction ({commit}) {
axios({method: 'GET', 'url': Constants.API_SERVER + 'site/user'})
.then(result => {
let data = result.data
commit(types.GET_USER, {data})
}, error => {
commit(types.GET_USER, {})
console.log(error.toString())
})
}
}
const mutations = {
[types.GET_USER] (state, {data}) {
state.user = data
}
}
export default { state, getters, actions, mutations }
Mutatinos
export const GET_LANGS = 'GET_LANGS'
export const GET_USER = 'GET_USER'
Store
import Vuex from 'vuex'
import Vue from 'vue'
import user from './modules/user'
import lang from './modules/lang'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user,
lang
}
})
Main app
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
Lang module, here is the place where I'm trying get store
import * as types from '../mutation-types'
import {axiosget} from '../../api/api'
const state = { langList: [] }
const getters = {
getLangs: state => state.langList
}
const actions = {
// this two action give me similar result
getLangsAction (context) {
axiosget('lang') // described below
},
getAnotherLangsAction (context) {
console.log(context.rootState.user) <----get Observer object
}
}
const mutations = {
[types.GET_LANGS] (state, {data}) {
state.langList = data
}
}
export default { state, getters, actions, mutations }
axiosget action, api module
import * as Constants from './../constants/constants'
import store from '../store/index'
import axios from 'axios'
export const axiosget = function (apiUrl, actionSuccess, actionError) {
console.debug(store.state.user) // <----get Observer object, previously described
// should append user token to axios url, located at store.state.user.access_token.token
axios({method: 'GET', 'url': Constants.API_URL + apiUrl
+ '?access_token=' + store.state.user.access_token.token})
.then(result => {
let data = result.data
// todo implement this
// }
}, error => {
if (actionError && actionError === 'function') {
// implement this
}
})
}
Component, that call dispatcher. If i get state via mapGetters in computed properties - there is no problems
<template>
<div>
{{user.access_token.token}}
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'ArticlesList',
computed: mapGetters({
user: 'getUser'
}),
created () {
this.$store.dispatch('getLangsAction')
this.$store.dispatch('getAnotherLangsAction')
}
}
</script>
What I'm trying to do in this code - get user access token in main site (after login) and all further manipulations with data will be produced via api host.
Let's say you want to fetch state an attribute userId from object userDetails in Vuex store module user.js.
userDetails:{
userId: 1,
username: "Anything"
}
You can access it in following way in action
authenticateUser(vuexContext, details) {
userId = vuexContext.rootState.user.userDetails.userId;
}
Note: After rootState and before file name user, add the path to the store module file if it is inside nested folders.
I'm experimenting with vuex and I was looking for best way to organize my vuex files I finished with something like this:
/src/store/user/state.js:
export default {
state: {
user: null
}
}
/src/store/user/getters.js:
export default {
getters: {
user (state) {
return state.user
}
}
}
/src/store/user/mutations.js:
export default {
mutations: {
'SET_USER' (state, user) {
state.user = user
}
}
}
/src/store/user/actions.js
export default {
actions: {
loginUser ({ commit }, params) {
commit('SET_USER', {id: 1})
}
}
}
/src/store/user/index.js
import state from './state'
import getters from './getters'
import actions from './actions'
import mutations from './mutations'
export default {
state,
getters,
actions,
mutations
}
/src/store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user
}
})
When I load my code it returns in console following error:
vuex: unknown getter: user
Each of your user-related files are using export default, which means when you import those files, you are naming the entire object being exported state, getters, etc.
So, in the scope of index, the state variable has a property named state, the getters variable has a property named getters, etc. And this is throwing things off.
You should export a const for each of these files instead:
export const state = {
user: null,
}
And then when importing grab the named const like so:
import { state } from './state'
Alternatively, you could just remove the properties for state, getters, etc. from each file:
// state.js
export default {
user: null,
}
And then import like you're doing already:
import state from './state'