Hi, after posting an item to my api endpoint successfully an item has been added to my list but in order to see this at the moment I need to refresh the browser which isn't ideal.
Here's my relevant pages:
TodoView.vue
<template>
<div>
<div v-if="!isLoading" class="container max-w-6xl mx-auto my-20">
<div class="flex justify-between mx-8 md:mx-4 mb-4">
<h2 v-show="!isLoading" class="text-4xl text-center">Todos</h2>
<AppButton
type="secondary"
:processing="isLoading"
@click.prevent="isOpen = true"
>
Add New Todo
</AppButton>
</div>
<ListItems :listItems="todos.data" type="todo" />
<Pagination
class="w-80 md:w-auto"
:data="todos"
@pagination-change-page="getPaginatedTodos"
>
<template #prev-nav>
<span>< Previous</span>
</template>
<template #next-nav>
<span>Next ></span>
</template>
</Pagination>
<ModalWindow :open="isOpen" @close="closeModal()">
<AddTodoForm @close="closeModal()" />
</ModalWindow>
</div>
</div>
</template>
<script>
import { ref } from "vue";
import axios from "axios";
import AppButton from "@/components/AppButton.vue";
import ListItems from "@/components/ListItems.vue";
import LaravelVuePagination from "laravel-vue-pagination";
import ModalWindow from "@/components/ModalWindow.vue";
import AddTodoForm from "@/components/todo/AddTodoForm.vue";
import { mapGetters } from "vuex";
import { GET_USER_TOKEN_GETTER } from "@/store/storeconstants";
export default {
name: "TodoView",
components: {
AppButton,
AddTodoForm,
ListItems,
Pagination: LaravelVuePagination,
ModalWindow,
},
computed: {
...mapGetters("auth", {
token: GET_USER_TOKEN_GETTER,
}),
},
data() {
return {
isLoading: false,
todos: [],
links: [],
isOpen: ref(false),
pagination: {
current_page: 1,
},
};
},
methods: {
async getPaginatedTodos(pageNo = 1) {
this.isLoading = true;
let response = await axios.get(
`todos?page=${pageNo}`,
"Bearer: " + this.token
);
try {
this.todos = response.data;
this.links = response.data.links;
this.pagination = response.data.links;
this.isLoading = false;
} catch (error) {
console.log("Error: ", error);
}
},
closeModal() {
this.isOpen = !this.isOpen;
},
},
mounted() {
this.getPaginatedTodos();
},
};
</script>
AddTodoForm.vue
<template>
<div class="flex flex-col w-100">
<form @submit.prevent="onAddTodo" class="flex flex-col">
<BaseInput
v-model="todo.title"
label="Title"
type="text"
class="border-2 p-2 rounded mb-4"
/>
<BaseInput
v-model="todo.description"
label="Description"
type="text"
class="border-2 p-2 rounded mb-4"
/>
<AppButton
type="submit"
class="rounded border-2 border-gray p-2"
@click="$emit('close')"
>
<div>Add Todo</div>
</AppButton>
</form>
</div>
</template>
<script>
import Swal from "sweetalert2";
import axios from "axios";
import AppButton from "@/components/AppButton.vue";
import BaseInput from "@/components/BaseInput.vue";
export default {
name: "AddTodoForm",
components: {
AppButton,
BaseInput,
},
data() {
return {
todo: {
title: "",
description: "",
},
alertShow: false,
alertClasses: "",
alertText: "",
};
},
methods: {
clearFields() {
this.todo.title = "";
this.todo.description = "";
},
onAddTodo() {
this.todo = {
title: this.todo.title,
description: this.todo.description,
};
try {
axios.post("todo", this.todo).then(() => {
Swal.fire({
title: `Successfully added`,
text: ` ${this.todo.title} has been added!`,
icon: "success",
});
this.clearFields();
});
} catch (error) {
console.log("ERROR: ", error);
}
},
},
};
</script>
ListItems.vue
<template>
<!-- Company List -->
<ul class="flex flex-wrap justify-between">
<li
class="max-w-160 w-full mx-4 md:mx-0 md:w-1/3"
v-for="(item, index) in list"
:key="item.id"
data-item="item"
>
<Company
v-if="type == 'company'"
:companyDetails="item"
data-item="company"
@remove="remove(index)"
/>
<Contact
v-if="type == 'contact'"
:contactDetails="item"
data-item="contact"
@remove="remove(index)"
/>
<Todo
v-if="type == 'todo'"
:todoDetails="item"
data-item="todo"
@remove="remove(index)"
@added="(newTodo) => addTodo(newTodo)"
/>
<Artwork
v-if="type == 'artwork'"
:artworkDetails="item"
data-item="artwork"
/>
</li>
</ul>
</template>
<script>
import Company from "@/components/company/Company.vue";
import Contact from "@/components/contact/Contact.vue";
import Todo from "@/components/todo/Todo.vue";
import Artwork from "@/components/gallery/Artwork.vue";
export default {
components: {
Company,
Contact,
Todo,
Artwork,
},
props: {
listItems: [],
type: {
type: String,
},
},
data() {
return {
list: [],
};
},
mounted() {
this.list = this.listItems;
},
methods: {
remove(index) {
this.list.splice(index, 1);
},
addTodo(newTodo) {
console.log("newTodo: ", this.newTodo);
this.todos.push(newTodo);
},
},
};
</script>
Todo.vue
<template>
<div class="bg-gray-200 h-100 p-4 rounded m-4">
<div class="my-2">
<span class="font-bold">({{ todo.id }}) {{ todo.title }}</span
><br />
{{ todo }}
{{ todo.description }}<br />
</div>
<div class="flex flex-row items-center justify-between">
<AppButton
type="delete"
:processing="isLoading"
@click.prevent="deleteTodo(todo.id)"
data-element="button"
>Delete <i class="fa-solid fa-trash"></i
></AppButton>
</div>
</div>
</template>
<script>
import Swal from "sweetalert2";
import { ref } from "vue";
import axios from "axios";
import AppButton from "@/components/AppButton.vue";
export default {
components: {
AppButton,
},
name: "ContactDetails",
props: {
todoDetails: {},
},
data() {
return {
title: "",
description: "",
isOpen: ref(false),
isEdit: false,
todo: this.todoDetails,
};
},
methods: {
deleteTodo(id) {
Swal.fire({
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete it!",
}).then((result) => {
if (result.isConfirmed) {
Swal.fire("Deleted!", "Your file has been deleted.", "success");
axios.delete(`todo/${id}`);
this.$emit("remove");
}
});
},
closeModal() {
this.isOpen = !this.isOpen;
},
},
};
</script>