I've been developing a news application using Vue 3 along with the News API.
My current focus is on implementing a search feature.
Within my App.vue
file, 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 trigger the search
event from the TopBar.vue
component where the search form resides:
<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 entered search query successfully reaches the root App.vue
component. My attempt is to pass it to the ArticleList.vue
component so that it can be included in the component's endpoint:
<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
https://i.stack.imgur.com/LWWAs.png
The issue
The searchString
prop within the endpoint
variable mentioned above doesn't update when performing a search (for example, searching for "money"). Upon console logging, the output is:
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
Queries
- What could be the mistake being made here?
- What would be the most effective method to resolve this inconsistency?