Steve
Steve

Reputation: 425

Why is this useFetch POST request payload in Nuxt 3 empty?

Request payload for the POST request below is just {"email":""} in the network tab.

When I have hardcoded email.value in the request body it works, but it doesn't seem to be getting the value from the v-model.

<form @submit.prevent="notifyMe" class="mt-10 max-w-md">
                <div class="flex gap-x-4">
                  <label for="email-address" class="sr-only"
                    >Email address</label
                  >
                  <input
                    v-model="email"
                    id="email"
                    name="email"
                    type="email"
                    autocomplete="email"
                    required
                    class="min-w-0 flex-auto rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    placeholder="Enter your email"
                  />

                  <button
                    :disabled="pending"
                    type="submit"
                    class="disabled:bg-indigo-400 inline-flex items-center gap-x-2 rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
                  >
                    Notify me
                    <ButtonSpinner v-show="pending" />
                  </button>
                </div>
              </form>

<script setup>
const config = useRuntimeConfig();
const email = ref("");

const notifyMe = () => {
  // Make the useFetch API call below
  return execute();
};

const { pending, execute } = useFetch("/notifyme", {
  immediate: false,
  baseURL: config.public.apiBase,
  method: "POST",
  body: {
    email: email.value,
  },
});
</script>

Upvotes: 0

Views: 2089

Answers (1)

Steve
Steve

Reputation: 425

In the end, I used useAsyncData instead to make the post request. I still don't understand the best way to fetch Data in Nuxt 3 but this code seems to work for me:

<script setup>
const config = useRuntimeConfig();
const formData = ref({
  email: "",
});

const notifyMe = async () => {
  execute();
};

const { status, execute } = useAsyncData(
  async () => {
    // Fetch data from the server using the provided function
    const response = await $fetch("/notifyme", {
      method: "POST",
      body: {
        email: formData.value.email,
      },
      baseURL: config.public.apiBase,
    });

    // Return the fetched data
    return response;
  },
  {
    // Set immediate to false to delay data fetching until execute is called
    immediate: false,
  }
);

</script>

<form @submit.prevent="notifyMe" class="mt-10 max-w-md">
                <div class="flex gap-x-4">
                  <label for="email-address" class="sr-only"
                    >Email address</label
                  >
                  <input
                    v-model="formData.email"
                    id="email"
                    name="email"
                    type="email"
                    autocomplete="email"
                    required
                    class="min-w-0 flex-auto rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                    placeholder="Enter your email"
                  />
                  <button
                    :disabled="status === 'pending'"
                    type="submit"
                    class="disabled:bg-indigo-400 flex justify-center items-center gap-x-2 rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 w-24 h-10"
                  >
                    <span v-show="status !== 'pending'"> Notify me </span>
                    <div
                      v-show="status === 'pending'"
                      class="flex items-center"
                    >
                      <ButtonSpinner />
                    </div>
                  </button>
                </div>
              </form>

Upvotes: 0

Related Questions