commit api data to vuex from component - vuejs2

I am trying to push data from an api call to my store, but I keep getting errors like commit is undefined and dispatch is undefined.
If I understood documents correctly I can only manipulate state from components by creating mutations? been going round in circles for an hour now and would appreciate some guidance.
in main.js
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
import 'es6-promise/auto'
Vue.config.productionTip = false
new Vue({
router,
render: (h) => h(App),
store: store,
}).$mount('#app')
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
images: [],
},
mutations: {
addImages(state, newImages) {
state.images = []
state.images.push(newImages)
},
},
})
Header.js component:
<template>
<div>
<h1>Nasa Image Search</h1>
<div class="search-container">
<form action="/action_page.php">
<input v-model="searchWord" type="text" placeholder="Search.." name="search" />
<button v-on:click.prevent="search" type="submit">Search</button>
</form>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Header',
data: () => ({
searchWord: "",
//images: [],
}),
methods: {
search() {
let url
this.searchWord
? url = `https://images-api.nasa.gov/search?q=${this.searchWord}&media_type=image`
: url = `https://images-api.nasa.gov/search?q=latest&media_type=image`
console.log(url) //bug testing
axios
.get(url)
.then(response => {
const items = response.data.collection.items
console.log(items)
this.$store.commit('addImages', items)
console.log(this.$store.state.images)
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

Your code is perfectly fine, please create a new file store.js as below and import it in main.js and it will work. In newer version of vuex eg 4.0 we do have createStore function using which we can include store code in main.js file itself.
store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: { images: [], },
mutations: {
addImages(state, newImages) {
state.images = []
state.images.push(newImages)
},
},
});
main.js
import Vue from "vue";
import App from "./App.vue";
import { store } from "./store";
import router from './router'
import 'es6-promise/auto'
Vue.config.productionTip = false;
new Vue({
router, store,
render: h => h(App)
}).$mount("#app");
in Vue 3 with Vuex 4 -> We can have store code inside main.js as below. doc link https://next.vuex.vuejs.org/guide/#the-simplest-store
import { createStore } from 'vuex'
import { createApp } from 'vue'
const store = createStore({
state () {
return {
}
}
})
const app = createApp({ /* your root component */ })
app.use(store)

Normally I create my Vuex 'store' in a separate file and import it into main.js.
I did a local experiment where I declared 'const store' in main.js AFTER instantiating new Vue() in main.js, as you are doing, and am getting errors.
Try declaring 'const store' BEFORE new Vue().

Related

Why Vue doesn't see vuex?

I work with microfrontend single-spa (https://single-spa.js.org/)
I create a store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
}
})
in src/main.js i import it
import Vue from 'vue';
import singleSpaVue from 'single-spa-vue';
import 'devextreme/dist/css/dx.light.css';
import App from './App.vue';
import store from './store';
console.log("πŸš€ ~ file: main.js ~ line 6 ~ store", store)
Vue.config.productionTip = false;
Vue.prototype.$bus = new Vue();
const vueLifecycles = singleSpaVue({
store,
Vue,
appOptions: {
render(h) {
return h(App, {
store,
props: {
},
});
},
},
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
in console.log store displayed, but in the app cnsole.log(this) does not contain store
I don't understand where I am connecting wrong?
According to the docs, store should be a subproperty of appOptions:
const vueLifecycles = singleSpaVue({
// store, ❌
Vue,
appOptions: {
store, βœ…
render(h) {
return h(App, {
// store, ❌
props: {},
})
},
},
})

Uncaught ReferenceError: photoModule is not defined

Uncaught ReferenceError: photoModule is not defined
Π•he first time I encountered such an error so that the vuex store does not find the module.
What could be the problem?
vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
photoModule
}
})
main.js
import store from './store'
Vue.prototype.axios = axios
Vue.config.productionTip = false
new Vue({
vuetify,
router,
store,
render: h => h(App)
}).$mount('#app')
photoModule
import axios from 'axios'
export default {
state: {
photos: []
},
mitations: {
setPhotos(state, payload) {
state.photos = payload
}
},
getters: {
getAllPhotos(state) {
return state.photos
}
},
actions: {
fetchPhotos(context) {
axios.get('https://jsonplaceholder.typicode.com/photos?_limit=10')
.then(response => this.photos = context.commit('setPhotos', response.data))
}
}
}
For the second day I have been sitting on this error. At least hint where something is wrong
You didn't import the module
import Vue from 'vue'
import Vuex from 'vuex'
import photoModule from './photoModule.js' // βœ… Add this
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
photoModule
}
})

vuex unknown local mutation type: updateValue, global type: app/updateValue. Mutations don't work

I want to apply mutations through actions to a variable in my vuejs application. But I get this error saying [vuex] unknown local mutation type: updateValue, global type: app/updateValue
Here is my store folder structure:
-store
-modules
-app
-actions.js
-getters.js
-mutations.js
-state.js
-index.js
-actions.js
-getters.js
-mutations.js
-state.js
-index.js
This is my ./store/index.js file:
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import getters from './getters'
import modules from './modules'
import mutations from './mutations'
import state from './state'
Vue.use(Vuex)
const store = new Vuex.Store({
namespaced: true,
actions,
getters,
modules,
mutations,
state
})
export default store
This is my ./store/modules/index.js:
const requireModule = require.context('.', true, /\.js$/)
const modules = {}
requireModule.keys().forEach(fileName => {
if (fileName === './index.js') return
// Replace ./ and .js
const path = fileName.replace(/(\.\/|\.js)/g, '')
const [moduleName, imported] = path.split('/')
if (!modules[moduleName]) {
modules[moduleName] = {
namespaced: true
}
}
modules[moduleName][imported] = requireModule(fileName).default
})
export default modules
This is my ./store/modules/app/actions.js:
export const updateValue = ({commit}, payload) => {
commit('updateValue', payload)
}
This is my ./store/modules/app/getters.js:
export const value = state => {
return state.wruValue;
}
This is my ./store/modules/app/mutations.js:
import { set, toggle } from '#/utils/vuex'
export default {
setDrawer: set('drawer'),
setImage: set('image'),
setColor: set('color'),
toggleDrawer: toggle('drawer')
}
export const updateValue = (state, payload) => {
state.wruValue = payload * 12;
}
This is my ./store/modules/app/state.js:
export default {
drawer: null,
color: 'green',
wruValues:1,
wruValue: 1,
}
and finally this is my vue component:
<v-btn #click="updateValue(10)">
SHOW
</v-btn>
import { mapActions } from 'vuex';
...mapActions ('app',[
'updateValue'
]),
So when I click on the button I expect to see the wruValue to change (I print the value somewhere else for testing purposes) but instead I get the error mentioned above. What's wrong with my code?
commit('updateValue', payload, {root: true})
But I find your use of namespacing odd. For my projects, I don't separate out files for getters, actions, etc, I separate out tasks, projects, companies, etc. But if it works for you, that's fine. It doesn't seem like the issue. If you still get an error, you might need to change "updateValue" to "mutations/updateValue" or something.
You should use this project structure:
src/store/modules/app.js
export const state = {
drawer: null,
color: 'green',
wruValues: 1,
wruValue: 1
}
export const mutations = {
UPDATE_VALUE: (state, payload) => {
state.wruValue = payload * 12
}
}
export const actions = {
updateValue: ({ commit }, payload) => {
commit('UPDATE_VALUE', payload)
}
}
export const getters = {
getWruValue: (state) => state.wruValue
}
src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const requireContext = require.context('./modules', true, /.*\.js$/)
const modules = requireContext.keys()
.map(file =>
[file.replace(/(^.\/)|(\.js$)/g, ''), requireContext(file)]
)
.reduce((modules, [name, module]) => {
if (module.namespaced === undefined) {
module.namespaced = true
}
return { ...modules, [name]: module }
}, {})
export default new Vuex.Store({
modules
})
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store/'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
src/App.vue
<template>
<div id="app">
<button #click="updateValue(10)">
SHOW
</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions('app', ['updateValue'])
}
}
</script>
Then if you want to add a new store namespace, u need to put it inside of src/modules folder.

How can I fix '[vuex] unknown action type: lookupName' within my Vue component?

I am having an issue calling up an action from my Vue component using this.$store.dispatch('lookupName'). I have tried console logging the this.$store method, but the actions within it are empty.
Main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { findCertificate } from '#/api';
Vue.use(Vuex)
const state = {
// single source of data
nameLookup: {},
}
const actions = {
// asynchronous operations
lookupName(context, form){
return findCertificate(form)
}
}
const store = new Vuex.Store({
state,
actions,
mutations,
getters
})
export default store
Vue Component
import VueRecaptcha from 'vue-recaptcha';
import { mapGetters, mapActions} from 'vuex'
export default {
created() {
},
methods: {
...mapActions({
lookupName: 'lookupName'
}),
...mapActions({
add: 'lookupName'
}),
onCaptchaVerified: function(recaptchaToken){
this.$refs.recaptcha.reset();
console.log(this.$store.dispatch('lookupName', this.form))
},
}
}
Why am I still getting this error? I have looked up many other people's questions about similar issues, but those solutions did not work for me.

Store referenced but not defined

Hey I have some bullshit issue with store not being defined. Any advice so I can move on and finish this software build? Store and contents of store appears in Vue Inspector tools. When put inline like below it breaks and renders blank - no DOM content inside App component.
App.vue offending excerpt
<div v-if="$store.state.showPreloader == true" id="preloaderWrap">
<div id="preloader"></div>
</div>
Store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
stuff
}
const mutations = {
stuff
}
const getters = {
stuff
}
const actions = {
stuff
}
export default new Vuex.Store({
state: state,
mutations: mutations,
getters: getters,
actions: actions
})
Main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import VueGraph from '../node_modules/vue-graph'
import VueMaterial from '../node_modules/vue-material'
import 'vue-material/dist/vue-material.min.css'
Vue.config.productionTip = false;
Vue.use(VueGraph);
Vue.use(VueMaterial);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
You need to init Vue with store:
new Vue({
el: '#app',
router,
store: store,
components: { App },
template: '<App/>'
})