I've been working on a review application with Vue.js that fetches random facts from an API (https://uselessfacts.jsph.pl/random.json?language=en) and allows users to provide feedback through radio buttons and text inputs. Once submitted, the feedback is displayed in a list under the form. However, I'm facing an issue where the page reloads by default after submission, causing the user input to be lost.
To prevent this, I tried adding 'prevent' to the HTML form tag like this:
<form v-on:submit.prevent="handleSubmit">
but it created another problem - without reloading the page, a new fact cannot be retrieved from the API.
The setup of my two Vue components is as follows:
//first component
<template>
<div v-if="randomFact">
<h3><span>Random fact: </span>{{this.randomFact.text}}</h3>
<form v-on:submit='handleSubmit'>
<input type="radio" name="reaction" id="positive" value="positive" v-model="reaction">
<label for="positive">Positive</label><br>
<input type="radio" name="reaction" id="neutral" value="neutral" v-model="reaction">
<label for="neutral">Neutral</label><br>
<input type="radio" name="reaction" id="negative" value="negative" v-model="reaction">
<label for="negative">Negative</label><br>
<br>
<label for="feedback">Feedback</label>
<br>
<textarea rows="4" cols="50" name="feedback" v-model="feedback"></textarea>
<br>
<input type="submit" value="Submit">
<br>
</form>
</div>
</template>
<script>
import { eventBus } from '../main.js';
import Review from '../classes/review.js';
export default {
name: "review-detail",
data(){
return {
randomFact:"",
reaction: "",
feedback:""
}
},
mounted(){
fetch('https://uselessfacts.jsph.pl/random.json?language=en').then(response=> response.json())
.then(randomFact=> this.randomFact= randomFact)
.catch(error=> console.log(error))
},
methods: {
handleSubmit(){
let review = new Review(this.randomFact.text, this.reaction, this.feedback);
eventBus.$emit('review-recorded', review)
}
}
}
</script>
//second component
<template>
<div>
<ul id="reviews" v-bind="reviews">
<li v-for="review in reviews" :key="review.reaction">
<p>Random fact: {{review.randomFact}}</p>
<p>Reaction: {{review.reaction}}</p>
<p>Feedback: {{review.feedback}}</p>
</li>
</ul>
</div>
</template>
<script>
import { eventBus } from '../main.js';
import Review from '../classes/review.js';
export default {
name:'reviews-list',
data(){
return{
reviews:[],
}
},
mounted(){
eventBus.$on('review-recorded', (review)=>{
this.reviews.push(review);
})
}
}
</script>
I need to figure out how to reload the first component to get new facts from the API without refreshing the second component. Am I handling the communication between these two components incorrectly in my Vue app? My goal is to save user input from the first component and display it in the second component while updating the first component with new random facts.