I have two components with the App.vue in my little project. The first is a form who add or update data and the second list all data in the database in a table. And in the table i have 2 actions delete and update . The delete, add and get work but if i want to edit a record i have a problem to fill the form due to the reactivity. I use pinia and composition API. My 2 components are in the app.vue file in two columns.
The code of the App.vue file
<template>
<div class="container">
<div class="row">
<h1 class="text-warning mb-5 mt-5 center">Students APP </h1>
</div>
<div class="row">
<div class="col-md-4">
<AddorModifyStudent/>
</div>
<div class="col-md-8">
<ListStudents/>
</div>
</div>
</div>
</template>
<script setup>
import AddorModifyStudent from './components/AddorModifyStudent.vue';
import ListStudents from './components/ListStudents.vue';
</script>
<style scoped>
</style>
The code of the pinia store is
import { defineStore } from 'pinia'
import axios from 'axios'
const config = {
headers: {
"Content-Type": "application/json",
}
}
export const useStudentStore = defineStore('students', {
state: () => ({
studentsList: null,
idStudentToModify: null,
student:{},
}),
getters:{
getStudentsList(state){
return state.studentsList
},
getidStudentToModify(state){
return state.idStudentToModify
},
getStudentInfos(state){
return state.student
}
},
actions: {
async getAllStudents() {
try{
const data = await axios.get("http://localhost:8080/api/students")
this.studentsList= data.data
} catch(e){
console.log(e)
}
},
async getStudent(id) {
try{
const data = await axios.get(`http://localhost:8080/api/students/${id}`)
this.student= data.data
} catch(e){
console.log(e)
}
},
async addStudent(firstname, lastname, email, phone) {
try{
const response = await axios.post("http://localhost:8080/api/students", {
"firstname": firstname,
"lastname": lastname,
"phone": phone,
"email": email
}, config)
}
catch(e){
console.log(e)
}
finally {
this.getAllStudents()
}
},
async updateStudent(id, firstname, lastname, email, phone) {
try{
const response = await axios.put(`http://localhost:8080/api/students/${this.idStudentToModify}`, {
""firstname": firstname,
"lastname": lastname,
"phone": phone,
"email": email
}, config)
}
catch(e){
console.log(e)
}
finally {
this.getStudentsList()
this.student= {}
}
},
async deleteStudent(id){
try{
const response = await axios.delete(`http://localhost:8080/api/students/${id}`)
console.log(response)
}
catch(e){
console.log(e)
}
finally {
this.getStudentsList()
}
},
}
})
This code for ListStudents.vue is:
<template>
<div>
<h2 class="mb-3">Students List</h2>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Firstname</th>
<th scope="col">Lastname</th>
<th scope="col">Email</th>
<th scope="col">Phone</th>
<th colspan="2" class="text-center">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="student in students">
<th scope="row">{{student.id}}</th>
<td>{{student.firstname}}</td>
<td>{{student.lastname}}</td>
<td>{{student.email}}</td>
<td>{{student.phone}}</td>
<td><button class="btn btn-warning" @click="updateStudent(student.id)">Update</button></td>
<td><button class="btn btn-danger" @click="deleteStudent(student.id)">Delete</button></td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import {useStudentStore} from "@/store/store"
import { computed, onMounted } from 'vue'
const store = useStudentStore()
onMounted(() => {
store.getAllStudents()
})
const students= computed(() => store.getStudentsList)
const deleteStudent = (id) => store.deleteStudent(id)
const updateStudent= (id) => {
store.idStudentToModify = id
store.getStudent(id)
}
</script>
<style>
</style>
and the code for the AddorModifyStudent.vue file is:
<template>
<div>
<h2 class="mb-3">Add Student</h2>
<form>
<div class="mb-3">
<label for="firstname" class="form-label">Firstname</label>
<input type="text" class="form-control" id="firstname" v-model="firstname">
</div>
<div class="mb-3">
<label for="lastname" class="form-label">Lastname</label>
<input type="text" class="form-control" id="lastname" v-model="lastname">
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" v-model="email">
</div>
<div class="mb-3">
<label for="tphone" class="form-label">Phone</label>
<input type="tel" class="form-control" id="phone" v-model="phone" >
</div>
<button type="submit" class="btn btn-warning" @click="sendOrUpdate">{{action}}</button>
</form>
</div>
</template>
<script setup>
import {ref, onMounted, reactive, watch, computed, toRaw} from "vue"
import { storeToRefs, } from 'pinia'
import {useStudentStore} from "@/store/store"
const store = useStudentStore()
let idStudentToModify = computed(() => store.idStudentToModify)
if (idStudentToModify.value != null) {
store.getStudent(idStudentToModify.value)
}
let prenom = store.idStudentToModify? ref(store.getStudentInfos.firstname) : ref("")
let nom = store.idStudentToModify? ref(store.getEtudiantInfos.lastname) : ref("")
let email = store.idStudentToModify? ref(store.getEtudiantInfos.email) : ref("")
let telephone = store.idStudentToModify? ref(store.etudiant.telephone) : ref("")
let action = computed(()=> idStudentToModify.value?"Update Student": "Add Student")
const sendOrUpdate = (e) => {
e.preventDefault();
try {
if(idEtudiantAModifier.value) {
store.updateStudent(id, firstname.value, lastname.value, email.value, phone.value)
} else {
store.addStudent(firstname.value, lastname.value, email.value, phone.value)
}
}
catch (e) {
console.log(e)
}
finally {
firstname.value=""
lastname.value =""
email.value=""
phone.value=""
}
}
</script>
<style>
</style>
That's it. My goal is if i click on update button in the list of students, the form should be automatically filled. The button add or update change automatically but the not the form. Thanks for your help.