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?