Siguiendo con el ejemplo que empezamos a trabajar en el último post dedicado al acceso de datos vía API con vue.js, vamos a implementar ahora los metodos necesarios para poder crear, actualizar, borrar y ver los datos guardados (CRUD).
En realidad, uno de los elementos del CRUD (Read), ya lo tenemos resuelto en el post anterior

ya que fuimos capaces de acceder a los datos y mostrarlos en pantalla al usuario.
Vamos a pasar al resto de acciones que vamos a tener disponibles. Iremos viendo en cada caso, la configuración necesaria en el fichero api_movies.js (revisar el post anterior), el código correspondiente a la acción en la vista Movies.vue y el codigo html que hemos de incluir en el template.
En todos los casos, el propio código está bastante documentado, con lo que no serán necesarias demasiadas explicaciones. Vamos a por ello.
Editar y borrar
Lo primero que haremos será crear dos botones en una nueva columna en la tabla donde mostramos los datos. Estos botones nos permitirán lanzar los eventos de edición y borrado.

Veamos el metodo en la llamada a la API
// LLAMADAs A LA API DE LAS PELÍCULAS
// api_moves.js
//....... codigo anterior......
// Modificar una película
async function updateMovie(movieId, updatedMovieData) {
try {
const token = getAccessToken(); // Obtiene el token de acceso
if (token) {
const response = await axios.put(`${API_MOVIES}${movieId}/`, updatedMovieData, {
headers: {
Authorization: 'Bearer ' + token,
},
});
return response.data;
} else {
console.error('Token de acceso no disponible');
return null;
}
} catch (error) {
console.error('Error al modificar detalles de la película:', error);
return null;
}
}
/ Exporta todas las funciones
export { getMovies, getMovieById, updateMovie}
En Movies.vue, preparamos el template para mostrar un formulario de edicion:
// Movies.vue
<!-- Formulario para la edición de las películas-->
<div v-if="selectedMovieIndex !== null">
<div class="edit-form">
<h3 class="mb-4">Editando Película</h3>
<form @submit.prevent="saveEditedMovie">
<div class="row">
<div class="col">
<input type="text" class="form-control" v-model="movies[selectedMovieIndex].title_movie" :placeholder="'Título'">
</div>
<div class="col">
<input type="text" class="form-control" v-model="movies[selectedMovieIndex].gender_movie" :placeholder="'Género'">
</div>
<div class="col">
<input type="text" class="form-control" v-model="movies[selectedMovieIndex].year_movie" :placeholder="'Año'">
</div>
<div class="col">
<input type="text" class="form-control" v-model="movies[selectedMovieIndex].director_movie" :placeholder="'Director'">
</div>
<div class="col">
<button type="submit" class="btn btn-primary mb-2" @click="saveEditedMovie">Guardar</button>
</div>
</div>
</form>
</div>
</div>
<!-- Formulario para la edición de las películas-->
Y el método correspondiente en el apartado script
data() {
return {
....
selectedMovieIndex: null,
....
};
},
// METODO PARA EDITAR PELICULAS
editMovie(index) {
this.selectedMovieIndex = index;
},
// METODO PARA GUARDAR LAS PELICULAS EDITADAS
async saveEditedMovie() {
if (this.selectedMovieIndex !== null) {
try {
const movieToEdit = this.movies[this.selectedMovieIndex]; // Obtener la película seleccionada para editar
const movieId = movieToEdit.id; // Obtener el ID de la película a modificar
const updatedMovieData = {
// Actualiza estos campos con los datos del formulario
title_movie: movieToEdit.title_movie,
gender_movie: movieToEdit.gender_movie,
year_movie: movieToEdit.year_movie,
director_movie: movieToEdit.director_movie,
};
const updatedMovie = await updateMovie(movieId, updatedMovieData);
if (updatedMovie) {
// Manejar la película actualizada (si es necesario)
console.log('Película actualizada:', updatedMovie);
// Actualizar la lista de películas
this.movies[this.selectedMovieIndex] = updatedMovie;
this.successMessage = '¡La película se ha actualizado correctamente!';
// El mensaje aparece durante 2 segundos
setTimeout(() => {
this.successMessage = '';
}, 2000);
} else {
this.errorMessage = 'Error al actualizar la película';
}
} catch (error) {
console.error('Error al guardar la película editada:', error);
this.errorMessage = 'Error al guardar la película editada';
} finally {
this.selectedMovieIndex = null; // Resetear la variable de índice de película seleccionada
}
} else {
this.errorMessage = 'No se ha seleccionado ninguna película para editar';
}
},


La reacción a la pulsación al boton de borrado es similar, en cuento a estructura, pero en esta ocasión muestra un alert de petición de confirmación al usuario. Vamos a verlo.
// LLAMADAs A LA API DE LAS PELÍCULAS
// api_moves.js
//....... codigo anterior......
// Eliminar una película por ID
async function deleteMovieById(movieId) {
console.log("La película a borrar es " + movieId);
try {
const token = getAccessToken(); // Obtiene el token de acceso
if (token) {
const response = await axios.delete(`${API_MOVIES}${movieId}/`, {
headers: {
Authorization: 'Bearer ' + token,
},
});
if (response.status === 200) {
return '¡La película se ha eliminado correctamente!';
} else {
return 'Error al eliminar la película';
}
} else {
console.error('Token de acceso no disponible');
return 'Token de acceso no disponible';
}
} catch (error) {
console.error('Error al eliminar la película:', error);
return 'Error al eliminar la película';
}
}
// Exporta todas las funciones
export { getMovies, getMovieById, updateMovie, deleteMovieById };
De vuelta a la vista, creamos el método de respuesta al evento click del boton de borrado
// METODO PARA BORRAR PELÍCULAS
async deleteMovie(index) {
const movieId = this.movies[index].id;
if (confirm('¿Estás seguro de que quieres borrar esta película?')) {
try {
const deleted = await deleteMovieById(movieId);
console.log(movieId);
if (deleted) {
console.log('Película eliminada con éxito');
// Eliminar la película del array local en Vue
//this.movies.splice(index, 1);
this.successMessage = '¡La película se ha eliminado correctamente!';
// El mensaje aparece durante 2 segundos
setTimeout(() => {
this.successMessage = '';
}, 2000);
// Después de eliminar, actualiza la lista de películas llamando a la función para obtener películas
await this.getMoviesAndDetails();
}
} catch (error) {
this.errorMessage = 'Error al eliminar la película';
}
}
},
De esta manera, el sistema pedirá confirmación al usuario antes de borrar un registro


Creando nueva películas
Para completar los procesos del CRUD, vamos a permitir al usuario crear sus propias películas, llamando a la API y con los correspondientes formularios y métodos en la vista Movies.vue
Siguiendo la estructura anterior vemos la llamada a la API
// LLAMADAs A LA API DE LAS PELÍCULAS
// api_moves.js
//....... codigo anterior......
// Crear una nueva película
async function createMovie(newMovieData) {
try {
const token = getAccessToken(); // Obtiene el token de acceso
if (token) {
const response = await axios.post(`${API_MOVIES}`, newMovieData, {
headers: {
Authorization: 'Bearer ' + token,
},
});
return response.data;
} else {
console.error('Token de acceso no disponible');
return null;
}
} catch (error) {
console.error('Error al crear la película:', error);
return null;
}
}
// Exporta todas las funciones
export { getMovies, getMovieById, updateMovie, deleteMovieById, createMovie };
Ahora montamos un boton para llamar a un evento que nos permita crear una película, usando un formulario similar al de edición, visto anteriormente
// Movies.vue
<!-- CODIGO ANTERIOR -->
<!-- Formulario para la creación de películas -->
<div v-if="isCreateFormVisible" class="edit-form">
<h3 class="mb-4">Crear Película</h3>
<form>
<div class="row">
<div class="col">
<input type="text" class="form-control" v-model="newMovie.title_movie" :placeholder="'Título'">
</div>
<div class="col">
<input type="text" class="form-control" v-model="newMovie.gender_movie" :placeholder="'Género'">
</div>
<div class="col">
<input type="text" class="form-control" v-model="newMovie.year_movie" :placeholder="'Año'">
</div>
<div class="col">
<input type="text" class="form-control" v-model="newMovie.director_movie" :placeholder="'Director'">
</div>
<div class="col">
<button type="submit" class="btn btn-primary mb-2" @click="saveNewMovie">Guardar</button>
</div>
</div>
</form>
</div>
<!-- Formulario para la creación de películas -->
<!-- Botón para mostrar el formulario de creación de película -->
<button class="btn btn-primary" @click="showCreateForm">Crear Película</button>
Ahora creamos las variables y métodos necesarios para gestionar la creación de registros
export default {
data() {
return {
....
// Objeto para almacenar los datos de la nueva película
newMovie: {
title_movie: '',
gender_movie: '',
year_movie: '',
director_movie: ''
},
......
};
},
// METODO PARA MOSTRAR EL FORMULARIO DE CREACION DE PELICULAS
showCreateForm() {
this.isCreateFormVisible = true;
// Limpiar los campos del nuevo formulario
this.newMovie = {
title_movie: '',
gender_movie: '',
year_movie: '',
director_movie: ''
};
},
// METODO PARA GUARDAR UNA NUEVA PELÍCULA
async saveNewMovie() {
if (this.newMovie.title_movie && this.newMovie.gender_movie && this.newMovie.year_movie && this.newMovie.director_movie) {
try {
const createdMovie = await createMovie(this.newMovie);
if (createdMovie) {
// Hacer algo con la película creada, por ejemplo, limpiar los campos del formulario
this.newMovie = {
title_movie: '',
gender_movie: '',
year_movie: '',
director_movie: ''
};
// Actualizar la lista de películas llamando a la función para obtener películas
await this.getMoviesAndDetails();
this.successMessage = '¡La película se ha creado correctamente!';
// El mensaje desaparece después de 2 segundos
setTimeout(() => {
this.successMessage = '';
}, 2000);
} else {
this.errorMessage = 'Error al crear la película';
}
} catch (error) {
console.error('Error al guardar la nueva película:', error);
this.errorMessage = 'Error al guardar la nueva película';
}
} else {
this.errorMessage = 'Por favor, completa todos los campos';
}
},
De esta forma, tenemos a disposición del usuario, un formulario para crear películas


Y la nueva película se quedará guardada en nuestra base de datos

Y esto es todo por el momento, en lo referido a las acciones que podemos llevar a cabo con bases de datos, APIS y un frontend como VUE.JS.
Como siempre, el código está disponible en mi repositorio de Github