Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

boyjarv's avatar

How can I show that an item has been added to my list after my POST axios is successful

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>&lt;&nbsp;Previous</span>
        </template>
        <template #next-nav>
          <span>Next&nbsp;&gt;</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 }})&nbsp;{{ 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&nbsp;&nbsp;<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>

0 likes
4 replies
AungHtetPaing__'s avatar
Level 22

@boyjarv emit event from AddTodoForm update todolist in TodoView

onAddTodo() {
      this.todo = {
        title: this.todo.title,
        description: this.todo.description,
      };
     axios.post("todo", this.todo)
		.then(() => {
          Swal.fire({
            title: `Successfully added`,
            text: ` ${this.todo.title} has been added!`,
            icon: "success",
          });
          this.clearFields();
		  this.$emit('addedTodo', this.todo)
        })
		.catch (error) {
        	console.log("ERROR: ", error);
     	}
    },

//TodoView.vue
<AddTodoForm @added-todo="updateTodoList" />

updateTodoList(todo) {
      this.todos.push(todo);
    },
1 like
boyjarv's avatar

@AungHtetPaing__ Thanks its getting into the emit but now I get:

Uncaught (in promise) TypeError: this.todos.push is not a function
AungHtetPaing__'s avatar

@boyjarv is your todos is array right? I see you are giving todos.data as props to ListItems so may be try this this.todos.data.push.

1 like
boyjarv's avatar

Thanks, I fixed it like this:

updateTodoList(todo) {
      this.todos.data.push({ ...todo });
    },

Please or to participate in this conversation.