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

boyjarv's avatar

Todos keeps on doubling on each page visit - NUXT

Here is my todos page:


<script setup>
import { ssrRef, useRouter } from "@nuxtjs/composition-api";
import { useTodo } from "@/store/todos";
const router = useRouter();
const todo = useTodo();
const title = ssrRef("");
const description = ssrRef("");
todo.getTodos();
const addTodo = () => {
  if (!title.value || !description.value) {
    alert("Please fill all the field");
  } else {
    const data = {
      title: title.value,
      description: description.value,
    };
    todo.addTodo(data);
  }
};
</script>
<template >
  <div
    class="main-content relative min-h-screen"
    :style="{
      'background-size': 'cover',
      'backdrop-filter': 'blur(5px)',
      //filter: 'blur(8px)',
    }"
  >
    <NavbarVue />
    <div class="container my-10 mx-auto max-w-xl bg-purple-400 rounded-xl">
      <form action="" class="p-5" @submit.prevent="addTodo">
        <h1 class="text-white text-center text-3xl">Add Todo</h1>
        <div class="my-3">
          <label for="" class="text-md font-semibold"> Enter your title </label>
          <input
            type="text"
            v-model="title"
            class="
              outline-none
              w-full
              py-2
              rounded
              bg-transparent
              border-b-2
              text-white text-lg
              placeholder-white
            "
            placeholder="Enter Your Title"
          />
        </div>
        <div class="my-3">
          <label for="" class="text-md font-semibold">
            Enter your description
          </label>
          <input
            type="text"
            v-model="description"
            class="
              outline-none
              w-full
              py-2
              rounded
              bg-transparent
              border-b-2
              text-white text-lg
              placeholder-white
            "
            placeholder="Enter Your Description"
          />
        </div>
        <button
          type="submit"
          class="
            rounded-md
            border
            px-10
            py-2
            bg-purple-600
            text-white text-xl text-semibold
            hover:bg-purple-700
          "
        >
          {{ useTodo.isloading ? "Todo...." : "Todo" }}
        </button>
      </form>
    </div>
    <h3>TODOS</h3>
    <div v-for="todo in todo.todos" :key="todo.id" class="text-white">
      <div v-for="todo in todo.todos" :key="todo.id" class="text-white">
        {{ todo }}
      </div>
    </div>
  </div>
</template>
<script>
import NavbarVue from "../../components/Navbar.vue";

export default {
  name: "TodosPage",
  components: {
    NavbarVue,
  },
};
</script>
<style>
.main-content {
  z-index: 1;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)),
    url("@/assets/Worthing.jpeg");
  min-width: "100vw";
  min-height: "100vh";
}
</style>

Here is my pinia store for my todos:

import { defineStore } from "pinia";
import axios from "@nuxtjs/axios";

export const useTodo = defineStore({
  id: "todo",
  state: () => ({
    token: localStorage.getItem("token") || "",
    todos: [],
    todo: {},
    isloading: false,
  }),
  actions: {
    // signup user
    async addTodo(data) {
      // to use fetch api
      this.isloading = true;

      const res = await fetch("http://127.0.0.1:8000/api/todo", {
        method: "POST",
        body: JSON.stringify(data),
        headers: {
          "Content-Type": "application/json",
          Authorization: "Bearer " + localStorage.getItem("token"),
        },
      });
      const output = await res.json();
      if (output.success) {
        this.isloading = false;
        alert(output.message);
        data.title = "";
        data.description = "";
      } else {
        this.isloading = false;
        alert(output.message);
      }
    },
    async getTodos() {
      this.isloading = true;
      console.log("Local storage: ", localStorage.getItem("token"));
      const res = await fetch("http://localhost:8000/api/todos", {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: "Bearer " + localStorage.getItem("token"),
        },
      });
      const output = await res.json();
      this.isloading = false;
      // this.todo = output;
      this.todos.push(output);
    },
  },
});

0 likes
5 replies
boyjarv's avatar

when I go to Todos page I get:

{ "id": 1, "title": "jiohjiuohoh", "description": "uihgiouhiuo", "created_at": "2022-09-11T13:20:31.000000Z", "updated_at": "2022-09-11T13:20:31.000000Z" }
{ "id": 2, "title": "huhiujhiIUhiuh", "description": "uihuih", "created_at": "2022-09-11T13:24:56.000000Z", "updated_at": "2022-09-11T13:24:56.000000Z" }
{ "id": 3, "title": "jiojuojj", "description": "IOJOJOJ", "created_at": "2022-09-11T13:26:18.000000Z", "updated_at": "2022-09-11T13:26:18.000000Z" }

great! But.... when I go home page and then back to Todos page, I get:

{ "id": 1, "title": "jiohjiuohoh", "description": "uihgiouhiuo", "created_at": "2022-09-11T13:20:31.000000Z", "updated_at": "2022-09-11T13:20:31.000000Z" }
{ "id": 2, "title": "huhiujhiIUhiuh", "description": "uihuih", "created_at": "2022-09-11T13:24:56.000000Z", "updated_at": "2022-09-11T13:24:56.000000Z" }
{ "id": 3, "title": "jiojuojj", "description": "IOJOJOJ", "created_at": "2022-09-11T13:26:18.000000Z", "updated_at": "2022-09-11T13:26:18.000000Z" }
{ "id": 1, "title": "jiohjiuohoh", "description": "uihgiouhiuo", "created_at": "2022-09-11T13:20:31.000000Z", "updated_at": "2022-09-11T13:20:31.000000Z" }
{ "id": 2, "title": "huhiujhiIUhiuh", "description": "uihuih", "created_at": "2022-09-11T13:24:56.000000Z", "updated_at": "2022-09-11T13:24:56.000000Z" }
{ "id": 3, "title": "jiojuojj", "description": "IOJOJOJ", "created_at": "2022-09-11T13:26:18.000000Z", "updated_at": "2022-09-11T13:26:18.000000Z" }
Niush's avatar
Niush
Best Answer
Level 50

Why have you commented this?

// this.todo = output;
this.todos.push(output);

The first one is the way to do it. Second one just keeps pushing new response to the previous state.

boyjarv's avatar

ok, I changed it to this now:

this.todo = output;
      // this.todos.push(output);

this is my state:

Screenshot-2022-09-11-at-19-28-51host an image

nothing is being output to the screen

Niush's avatar

@boyjarv Looks like this is what you need:

this.todos = output.todos;
// this.todos -> (plural) is your pinia array of todos
// output.todos -> is the array coming from the backend (output only is the json object)

Please or to participate in this conversation.