Home > database >  Vuejs search function doesn't work properly
Vuejs search function doesn't work properly

Time:09-21

I have a search bar that is in my navbar component and with Axios, I get the articles filtered.

export default {
  data() {
    return {
      articles: [],
      article: {},
      search: '', 
    }
  },
  methods: {
    getArticles() {
      const url = `${baseApiUrl}/search?search=${this.search}`;
      axios(url).then((res) => {
        this.articles = res.data;
      });
    }
  },
  watch: {
    search() {
      const route = {
        name: 'searchArticles'
      }
      if(this.search !== '') {
        route.query = {
          search: this.search
        }
      }
    },
    '$route.query.search': {
      immediate: true,
      handler(value) {
        this.search = value
      }
    }
  },
};
</script>
<template>
  <header class="navbar">
  
    <form class="searchInput">
      <input  v-model="search" @keyup.enter="getArticles()" placeholder="Search..." />
      <router-link :to="{ path: '/search', query: { search: this.search }}">
      <button type="submit">
        <font-icon class="icon" :icon="['fas', 'search']"></font-icon>
      </button>
      </router-link>
    </form>
    
  </header>
</template>

And I have my searchResult component to render the search result.

export default {
  data() {
    return {
      articles: [],
      article: {},
      search: ''
    }
  },
  created() {
    const url = `${baseApiUrl}/search?search=${this.search}`;
    axios(url).then((res) => {
      this.articles = res.data;
    });
  },
  watch: {
    search() {
      const route = {
        name: 'searchArticles'
      }
      if(this.search !== '') {
        route.query = {
          search: this.search
        }
      }
    },
    '$route.query.search': {
      immediate: true,
      handler(value) {
        this.search = value
      }
    }
  },
};
</script>
<template>
  <div>
    <div class="result-search">  
      <ul>
        <li v-for="(article, i) in articles" :key="i">
          <ArticleItem :article="article" />
        </li>
      </ul>
    </div>
  </div>
</template>

When I search for the first time it takes me to /search?... and shows the search result, but if I enter another value in the field just my URL changes from /search?search=a to /search?search=b and the result remains that of search A and only when I reload the page does it bring me the result of search B. Why does it happen? all my content is centered within my content component through the

my app component:

<template>
  <div id="app">
    <Header :hideUserDropdown="!user" />
    <Loading v-if="validatingToken" />
    <Content v-else />
    <Footer />
  </div>
</template>

CodePudding user response:

The axios call for searching your data currently exists in your created hook. This means it will only run on initial load of that page/component.

Move your search functionality into a method and invoke it from your watcher, ie

watch: {
  '$route.query.search': {
    immediate: true,
    fetchArticles(value)
  }
},
methods: {
  async fetchArticles(val) {
    let url = `${baseApiUrl}/search?search=${val}`
    try {
      let res = await axios(url)
      this.articles = res.data
    } catch (error) {
      console.log(`An error occurred attempting to fetch articles with search term of ${val}: `, error)
    } finally {
      // do something here if you need
    }
  }
}

The Vue docs are great if ever you get stuck. Here's a link to Vue's lifecycle hooks and when you can use them :)

Vue lifecycle hooks

  • Related