简体   繁体   中英

Items being searched depend on previous result

I'm pretty new to Vue and have recently dug into Vuex. I'm attempting to search through an API. The initial search works as intended. However, if a search is performed with a different query, only what was previously returned is searched through.

For example, if I searched 've', both 'Vettel' and 'Verstappen' would return as expected. However if I then search for anything without the letters previously returned, nothing appears, eg 'ham' when searching for Hamilton afterwards would not return anything.

I've tried modifying the mutations, but I'm not sure where I'm going wrong.

Here's the component:

<template>
  <transition
    appear
    appear-class="fade-enter"
    appear-to-class="fade-enter-to"
    appear-active-class="fade-enter-active"
  >
    <div>
      <h3>Current Standings</h3>

      <input type="text" v-model="searchQuery" v-on:input="search" placeholder="search driver">

      <table class="standings">
        <thead>
          <th>Position</th>
          <th>Driver Name</th>
          <th>Nationality</th>
          <th>Team</th>
          <th>Wins</th>
          <th>Points</th>
        </thead>
        <tbody>
          <tr v-for="standing in ALL_STANDINGS" :key="standing.position" class="standing">
            <td>{{standing.position }}</td>
            <td>{{standing.Driver.driverId | last-name | to-title-case}}</td>
            <td>{{standing.Driver.nationality | to-title-case}}</td>
            <td>{{standing.Constructors[0].constructorId | to-title-case}}</td>
            <td>{{standing.wins }}</td>
            <td>{{standing.points}}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </transition>
</template>

<script>
import styles from "../styles/styles.scss";
import { mapState, mapGetters, mapActions, mapMutations } from "vuex";

export default {
  name: "CurrentStandings",

  data() {
    return {
      searchQuery: ""
    };
  },

  created() {
    this.fetchStandings();
  },

  mounted() {
    this.created = true;
  },

  computed: {
    ...mapState(["standings", "filter"]),
    ...mapGetters(["ALL_STANDINGS", "GET_SEARCH", "FILTERED_SEARCH"])
  },

  methods: {
    ...mapActions(["fetchStandings"]),
    ...mapMutations(["SET_SEARCH", "SET_FILTER"]),

    search: function() {
      // set SEARCH to input
      this.$store.commit("SET_SEARCH", this.searchQuery);
      // return matches between ALL_STANDINGS and SEARCH
      this.SET_FILTER(
        this.ALL_STANDINGS.filter(standing => {
          return standing.Driver.driverId.match(this.GET_SEARCH);
        })
      );
    }
  }
};
</script>

and here's the standings.js module:

import axios from 'axios';

const state = {
  standings: [],
  filter: [],
  search: '',
};

const getters = {
  /* eslint no-shadow: ["error", { "allow": ["state"] }] */
  ALL_STANDINGS: state => state.standings,
  FILTERED_STANDINGS: state => state.filter,
  GET_SEARCH: state => state.search,

};

const mutations = {
  SET_STANDINGS: (state, standings) => (state.standings = standings),
  SET_SEARCH: (state, search) => (state.search = search),
  SET_FILTER: (state, filter) => (state.standings = filter),
  RESET_STANDINGS: (state, standings) => (state.filter = standings),

};


const actions = {
  async fetchStandings({ commit }) {
    const response = await axios.get('https://ergast.com/api/f1/current/driverStandings.json');

    commit('SET_STANDINGS', response.data.MRData.StandingsTable.StandingsLists[0].DriverStandings); // response.data is passed to 'standings' in the mutation (2nd arg)
  },

};

Any help would be greatly appreciated! Thanks :)

You should not modify initial dataset when performing filtering:

  SET_FILTER: (state, filter) => (state.standings = filter),

should be

  SET_FILTER: (state, filter) => (state.filter = filter),

I figured it out by using simplifying the project with fewer mutations and used getters, rather than modifying the state directly:

  data() {
    return {
      searchQuery: "",
    };
  },

  created() {
    this.fetchStandings();
  },

  computed: {
    ...mapState(["standings", "search", "filter"]),
    ...mapGetters(["filteredStandings", "sortedFilteredStandings"])
  },

  methods: {
    ...mapActions(["fetchStandings"]),
    ...mapMutations(["SET_SEARCH"]),

    filterStandings() {
      this.$store.commit("SET_SEARCH", this.searchQuery);
    }
  }

The store:

const state = {
  standings: [],
  search: '',
};

const getters = {

  filteredStandings: state => state.standings.filter(standing => standing.Driver.driverId.match(state.search)),
};

const mutations = {
  SET_STANDINGS: (state, standings) => (state.standings = standings),
  SET_SEARCH: (state, search) => (state.search = search),
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM