I have a SearchBar.vue child page with a form in this this code :
<template>
<div>
<form @submit.prevent="SearchMovies()">
<input
type="text"
placeholder="Effectuez une recherche"
v-model="search"
/>
<button
type="submit"
@click="$emit('get-movies', movies)"
>
CHERCHER
</button>
</form>
</div>
</template>
And my SearchMovies() function looks like :
setup() {
const search = ref("");
const movies = ref([]);
function SearchMovies () {
if (search.value != "") {
fetch(`${process.env.VUE_APP_API_URL_CALL_TWO}${search.value}`)
.then((response) => response.json())
.then((data) => {
movies.value = data.contents;
search.value = "";
console.log(
"Movies data from SearchBar.vue when fired up: ",
movies.value
);
});
}
this.$emit('get-movies', movies)
}
This is how I have tried to add the emit line
this.$emit('get-movies', movies)
And I receive the emitted data from SearchMovies() function to my parent Home.vue page like this :
<template>
<div>
<router-link to="/" href="/"
><img alt="App logo" src="../assets/logo.png"
/></router-link>
<SearchBar @get-movies="getMovies($event)" />
<MovieList :movies="movies" />
</div>
</template>
methods: {
getMovies: function (movies) {
(this.movies = movies),
console.log("Movies data from Home.vue when fired up: ",
movies);
},
},
The problem is that I am not getting the movies data and when I console.log it in the Home.vue page
Movies data from Home.vue when fired up: Proxy {}
CodePudding user response:
In your search bar, the @click event is never actually invoking the SearchMovies method. Try converting
<button type="submit" @click="searchMovies">...</button>
You're not exporting the function in your setup, at the bottom of setup
setup (_, {emit}) {
const search = ref("")
const movies = ref([])
const SearchMovies = () => {
const value = await fetch(`${process.env.VUE_APP_API_URL_CALL_TWO}${search.value}`)
const data = await value.json()
movies.value = data.contents
search.value = ""
console.log("Movies data from SearchBar.vue when fired up: ", movies.value);
emit('get-movies', movies.value)
}
return { search, movies, SearchMovies }
}
In your fetch statement, you're going to have some async code issue, the fetch statement will run, but then it will skip the await callbacks in favor of doing this.$emit. I'd convert it to Then, finally, I wouldn't catch the value in Home.vue with
<SearchBar @get-movies="getMovies($event)" />
Instead, just use @get-movies="getMovies"
You don't actually need make it call a function, it will just do it on it's own and I find trying to use the event bus causes confusion sometimes. You only need to use it if you have specific data from the template you could pass into it, like in a v-for loop you could pass in the specific object. Let me know if you need me to clarify anything so you can better understand why it's built like this.
<template>
<div >
<input
type="text"
placeholder="Effectuez une recherche"
v-model="search"
/>
<button
@click="SearchMovies"
>
CHERCHER
</button>
</div>
</template>