1

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>


2 Answers 2

1

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)
Sign up to request clarification or add additional context in comments.

1 Comment

perfect thanks for the comprehensive answer
1

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().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.