简体   繁体   中英

When I do a post request to create a single user, it creates 6

I have a minimal reproducible example here https://github.com/ChristianOConnor/fresh-handler-fetch-reproduce . This app is a deno fresh boiler plate with an added view called create . You land on a simple (but ugly) form view where you make a new user by typing in an email and key then pressing submit . This is the screen:
在此处输入图像描述

When I hit submit, the screen doesn't change but I get this in my web console.

在此处输入图像描述

What's even weirder is that when I check my database I have 6 entries of the same email and key. I have no idea why this is happening. I only pressed the button once:

在此处输入图像描述

The three files where pretty much all of the create page logic is happening is create.tsx , createUser.tsx and Creator.tsx

create.tsx:

import Layout from '../components/layouts.tsx';
import Creator from "../islands/Creator.tsx"

export default function User(props: PageProps) {
    return (
        <Layout>
            <Creator />
        </Layout>
    )
}

createUser.tsx:

import { Handlers, PageProps } from "$fresh/server.ts";
import UserDb from "../../database.ts";

export const handler = {
  POST: async (request, ctx) => {
    const reqJsn = (await request.json());
    const body = reqJsn;
    const email = body.email;
    const key = body.key;
    console.log(email);
    console.log(key);

    if (!email || !key) {
      ctx.status = 422;
      ctx.body = { msg: "Incorrect user data. Email and key are required" };
      return;
    }

    const userId = await UserDb.create({
      email: email,
      key: key,
      created_at: new Date()
    });

    ctx.body = { msg: "User created", userId };
  }
}

Creator.tsx:

// import { useState } from "preact/hooks";
import { useState, useEffect } from "preact/hooks";
import { Handlers, PageProps } from "$fresh/server.ts";
import UserDb from "../database.ts";

interface CreatorProps {
    email: string,
    key: string
}

export default function Creator(props: CreatorProps) {
  async function handleSubmit(event) {
    event.preventDefault();
    const emailInput = event.target.email;
    const ageInput = event.target.key;
    console.log(emailInput.value);
    console.log(ageInput.value);
    const resp = await createNewUser(emailInput.value, ageInput.value);
    return resp
  };

  async function createNewUser(email, key) {
    const rawPosts = await fetch('http://localhost:8000/api/createUser', {
      "method": "POST",
      "headers": {
        "content-type": "text/plain"
      },
      "body": JSON.stringify({
        email: email,
        key: key,
      })
    });
    console.log(rawPosts);
  }
    return (
      <div>
        <h1 class="text rounded-lg p-4 my-8"> Search </h1>
        <form method="post" onSubmit={async (e) => handleSubmit(e)}>
          <input class="center rounded-lg p-4 my-8" id="email" name="email" />
          <input class="center rounded-lg p-4 my-8" id="key" name="key" />
          <br />
          <button
              class="px-5 py-2.5 text-sm font-medium bg-blue-600 rounded-md shadow disabled:(bg-gray-800 border border-blue-600 opacity-50 cursor-not-allowed)"
              type="submit">Submit
          </button>
        </form>
        <br />
        {/* <ul>
          {results.map((name) => <li key={name}>{name}</li>)}
        </ul> */}
      </div>
    );
  };

Again, I provided a minimal reproducible example. to run it you need a postgres instance running, create a .env file in the root directory of the project and add your postgres variables like this:
.env:

POSTGRES_USER=postgresuserone
POSTGRES_PASSWORD=pass2woR3d
POSTGRES_DB=postgresdbone

go to the root directory of the repo and type deno task start in your terminal and it works. Remember to navigate to localhost:8000/create , fill in the 2 field and press submit. You will now have 6 entries in your db.

I fixed it, the key was that the POST request action was never actually returning. I added:

const res = new Response(null, {
      status: 302,
      headers: new Headers({
        location: 'localhost' + '../../../create',
      }),
    });
    return res;

to the end of createUser.tsx (also renamed createUser.tsx to createUser.ts ) and it only posted 1 new user to the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM