I have been working on a news app, using Vue 3 and the News API.
I am currently working on a search functionality.
In App.vue I have:
<template>
  <TopBar @search="doSearch" />
  <div class="container">
     <HomeView searchString="searchTerm" v-if="!searchTerm.length" />
     <SearchResultsView searchString="searchTerm" v-if="searchTerm.length" />
  </div>
  <AppFooter />
</template>
<script>
import TopBar from '@/components/TopBar.vue';
import AppFooter from '@/components/AppFooter.vue';
import HomeView from '@/views/HomeView.vue';
import SearchResultsView from '@/views/SearchResultsView.vue';
export default {
  name: 'App',
  components: {
    TopBar,
    AppFooter,
    HomeView,
    SearchResultsView
  },
  data: () => ({
    searchTerm: ''
  }),
  methods: {
    doSearch: function(searchTerm) {
      this.searchTerm = searchTerm;
      console.log(this.searchTerm);
    }
  }
}
</script>
I emit the search event form the TopBar.vue component, where the search form is:
<template>
  <nav class="navbar py-1 sticky-top navbar-expand-md">
    <div class="container-fluid">
      <form ref="searchForm" class="search_form w-100 mx-auto mt-2 mt-md-0">
          <div class="input-group">
            <input
              @change="handleChange"
              v-model="searchTerm"
              class="form-control search-box"
              type="text"
              placeholder="Search..."
            />
            <div class="input-group-append">
              <button class="btn" type="button">
                <font-awesome-icon :icon="['fas', 'search']" />
              </button>
            </div>
          </div>
        </form>
    </div>
  </nav>
</template>
<script>
export default {
  name: "TopBar",
  methods: {
    handleChange(event){
      this.$emit('search', event.target.value)
    }
  }
};
</script>
The search string is correctly "captured" by the root App.vue component. I try to pass it to the ArticleList.vue component, so that it becomes a part of the endpoint used by the component:
<template>
  <div v-if="articles.length" class="row">
    <div
      v-for="article in articles"
      :key="article._id"
      class="col-xs-12 col-sm-6 col-lg-4 col-xl-3"
    >
      <ArticleCard :article="article" />
    </div>
  </div>
  <p v-else class="text-center">
    No articles to display
  </p>
</template>
<script>
import ArticleCard from './ArticleCard.vue';
export default {
  name: "NewsList",
  components: {ArticleCard},
  props: {
    whatToShow: {
      type: String,
      required: true,
    },
    searchString: {
      type: String,
      required: true,
      default: ''
    }
  },
  data: () => ({
    language: 'en',
    page_size: 24,
    current_page: 1,
    articles: [],
  }),
  mounted() {
    this.getArticles();
  },
  methods: {
    getArticles() {
      let endpoint = `${process.env.VUE_APP_API_URL}/${this.$props.whatToShow}?q=${this.$props.searchString}&language=${this.language}&page_size=${this.page_size}&page=${this.current_page}&apiKey=${process.env.VUE_APP_API_KEY}`;
      console.log(endpoint);
      this.$axios
        .get(endpoint)
        .then((response) => {
          this.articles = response.data.articles;
          console.log(this.articles);
        })
        .catch((err) => console.log(err));
    },
  }
};
Screenhot
The problem
The searchString prop in the endpoint variable above does not update upon doing a search (with "money" for example) and console.log(endpoint) outputs
https://newsapi.org/v2/everything?q=&language=en&page_size=24&page=1&apiKey=myappykey123secret
instead of
https://newsapi.org/v2/top-headlines?q=money&language=en&page_size=24&page=1&apiKey=myappykey123secret
Questions
- What am I doing wrong?
- What is the most reliable way to fix this issue?

 
     
     
     
     
    