Skip to content
Advertisement

Search input using a query using Vuex and Axios

I’m trying to make a search input where I input a query and that query gets added to the API call and returns me the data that I want, here’s a sample of my code

      <input
    class="rounded-l-full w-full py-6 px-6 text-gray-700 leading-tight focus:outline-none"
    id="search"
    type="text"
    placeholder="Search"
    v-bind="query"
  />

    <button
      class="bg-blue-900 text-white rounded-full p-2 hover:bg-blue-700 focus:outline-none w-12 h-12 flex items-center justify-center"
      @click="getSearchResults()"
    >
      <font-awesome-icon :icon="['fas', 'search']" />
    </button>

My JS:

    <script>
import { mapActions, mapGetters, mapState } from "vuex";

export default {
  name: "Main",
  data() {
    return {};
  },
  computed: {
    ...mapGetters(["searchResult"]),
    ...mapState({
      query: (state) => state.query,
    }),
  },
  methods: {
    ...mapActions(["getSearchResults"]),
  },
};
</script>

My vuex module:

    import axios from "axios";

const state = {
  results: [],
  query: "",
};

const getters = {
  searchResult: (state) => state.results,
};

const actions = {
  async getSearchResults() {
    let query = state.query;
    const res = await axios.get(
      `https://www.theaudiodb.com/api/v1/json/1/search.php?s=${query}`
    );

    res.data.artists.forEach((artist) => state.results.push(artist));
  },
};

const mutations = {
  returnResults: (state, results) => (state.results = results),
};

export default {
  state,
  getters,
  actions,
  mutations,
};

The search query is not getting passed on the input, if I put something on the query from the Vuex module I get the correct results but if I input something and click the search button I get the default results of the api JSON which means my input is not working, I’d appreciate some help and thanks in advance!

Advertisement

Answer

First thing is that your using v-bind incorrectly, better use v-model:

<input
    class="rounded-l-full w-full py-6 px-6 text-gray-700 leading-tight focus:outline-none"
    id="search"
    type="text"
    placeholder="Search"
    v-model="query"
  />

second thing organize better your code when you are using vuex, I would do it of this way:

Template:

// pass the variable query to the funcion getSearchResults
<button
      class="bg-blue-900 text-white rounded-full p-2 hover:bg-blue-700 focus:outline-none w-12 h-12 flex items-center justify-center"
      @click="getSearchResults(query)"
    >
      <font-awesome-icon :icon="['fas', 'search']" />
    </button>

JS:

// Only import mapActions and mapGetters
// create the variable query inside of data() for v-model
<script>
import { mapActions, mapGetters} from "vuex";

export default {
  name: "Main",
  data() {
    return {
         query:"",
      };
  },
  computed: {
    ...mapGetters(["searchResult"]),
   
    }),
  },
  methods: {
    ...mapActions(["getSearchResults"]),
  },
};
</script>

VUEX:

import axios from "axios";

const state = {
  results: [],
};

const getters = {
  searchResult: (state) => state.results,
};

const actions = {
  async getSearchResults({commit}, query) {
    const res = await axios.get(
      `https://www.theaudiodb.com/api/v1/json/1/search.php?s=${query}`
    );
    // Execute the mutation which receive the data and pass to the state
    commit('returnResults', res.data.artists)
  },
};

const mutations = {
  returnResults: (state, results) => (state.results = results),
};

export default {
  state,
  getters,
  actions,
  mutations,
};
Advertisement