next-learn icon indicating copy to clipboard operation
next-learn copied to clipboard

createInvoice and updateInvoice should maybe have Promise<State> as return type

Open nemchik opened this issue 1 year ago • 22 comments

I just worked through chapter 14 https://nextjs.org/learn/dashboard-app/improving-accessibility and took note that TypeScript complains when using useFormState because the action functions (createInvoice and updateInvoice) differ in type from the initialState being passed. I've got my project deployed on Vercel (per the instructions in chapter 6 https://nextjs.org/learn/dashboard-app/setting-up-your-database also see P.S. note on this chapter) and the build log outputs:

[16:39:50.854] Failed to compile.
[16:39:50.855] 
[16:39:50.855] ./app/ui/invoices/create-form.tsx:17:29
[16:39:50.855] Type error: No overload matches this call.
[16:39:50.856]   Overload 1 of 2, '(action: (state: { errors: { customerId?: string[] | undefined; amount?: string[] | undefined; status?: string[] | undefined; }; message: string; } | { message: string; errors?: undefined; }) => { errors: { ...; }; message: string; } | { ...; } | Promise<...>, initialState: { ...; } | { ...; }, permalink?: string | undefined): [state: ...]', gave the following error.
[16:39:50.856]     Argument of type '(prevState: State, formData: FormData) => Promise<{ errors: { customerId?: string[] | undefined; amount?: string[] | undefined; status?: string[] | undefined; }; message: string; } | { ...; }>' is not assignable to parameter of type '(state: { errors: { customerId?: string[] | undefined; amount?: string[] | undefined; status?: string[] | undefined; }; message: string; } | { message: string; errors?: undefined; }) => { errors: { ...; }; message: string; } | { ...; } | Promise<...>'.
[16:39:50.856]       Target signature provides too few arguments. Expected 2 or more, but got 1.
[16:39:50.856]   Overload 2 of 2, '(action: (state: { errors: { customerId?: string[] | undefined; amount?: string[] | undefined; status?: string[] | undefined; }; message: string; } | { message: string; errors?: undefined; }, payload: FormData) => { ...; } | ... 1 more ... | Promise<...>, initialState: { ...; } | { ...; }, permalink?: string | undefined): [state: ...]', gave the following error.
[16:39:50.857]     Argument of type '{ message: null; errors: {}; }' is not assignable to parameter of type '{ errors: { customerId?: string[] | undefined; amount?: string[] | undefined; status?: string[] | undefined; }; message: string; } | { message: string; errors?: undefined; }'.
[16:39:50.858]       Type '{ message: null; errors: {}; }' is not assignable to type '{ errors: { customerId?: string[] | undefined; amount?: string[] | undefined; status?: string[] | undefined; }; message: string; }'.
[16:39:50.858]         Types of property 'message' are incompatible.
[16:39:50.858]           Type 'null' is not assignable to type 'string'.
[16:39:50.858] 
[16:39:50.858] [0m [90m 15 |[39m [36mexport[39m [36mdefault[39m [36mfunction[39m [33mForm[39m({ customers }[33m:[39m { customers[33m:[39m [33mCustomerField[39m[] }) {[0m
[16:39:50.858] [0m [90m 16 |[39m   [36mconst[39m initialState [33m=[39m { message[33m:[39m [36mnull[39m[33m,[39m errors[33m:[39m {} }[33m;[39m[0m
[16:39:50.858] [0m[31m[1m>[22m[39m[90m 17 |[39m   [36mconst[39m [state[33m,[39m dispatch] [33m=[39m useFormState(createInvoice[33m,[39m initialState)[33m;[39m[0m
[16:39:50.858] [0m [90m    |[39m                             [31m[1m^[22m[39m[0m
[16:39:50.858] [0m [90m 18 |[39m[0m
[16:39:50.858] [0m [90m 19 |[39m   [36mreturn[39m ([0m
[16:39:50.858] [0m [90m 20 |[39m     [33m<[39m[33mform[39m action[33m=[39m{dispatch}[33m>[39m[0m
[16:39:50.932] Error: Command "npm run build" exited with 1
[16:39:51.223] 

(sorry for all the special characters representing colors, it's copied directly from the output)

I found that seemingly the cleanest way to resolve this is to add Promise<State> as the return type of the functions createInvoice and updateInvoice in app/lib/actions.ts

export async function createInvoice(
  prevState: State,
  formData: FormData
): Promise<State> {
export async function updateInvoice(
  id: string,
  prevState: State,
  formData: FormData
): Promise<State> {

I'm still learning quite a bit, and this might not be the best solution, but it does seem to resolve the errors. My initial instinct as to why this might be wrong is both of those functions end with

  revalidatePath("/dashboard/invoices");
  redirect("/dashboard/invoices");

Neither of those lines imply a return of State as far as I can tell, so maybe more information could be provided to clarify what's going on here. I know the Promise part is because the functions are async so they can await the sql calls.


P.S. per the instructions in chapter 6 when deploying from GitHub to Vercel I receive errors about the missing alt attributes that are later added in chapter 14. I figured it would be easy to add on my own but I looked ahead in the material to see it was covered in a later chapter and waited patiently, but there was no indication in chapter 6 that this was expected. This topic could warrant a separate issue, and the outcome could either be to cover the alt attribute requirement sooner so that the Vercel deploy can be successful, or somehow otherwise keep that code commented until it's time to cover accessibility in chapter 14, or at least add some notes in chapter 6 about the deploy failing until you reach chapter 14 to correct the alt attributes (although that is quite a few chapters to cover between 6 and 14).

nemchik avatar Nov 18 '23 23:11 nemchik

My P.S. note may be resolved by https://github.com/vercel/next-learn/pull/468 I had not considered leaving the alt attributes blank, but that pretty much covers it.

nemchik avatar Nov 19 '23 00:11 nemchik

@nemchik, I ran into same issue but the issue actually was that I didn't fully change the createInvoice. In sql try/catch block the earlier version returns string when error but it should return { message: 'Database Error: Failed to Create Invoice.'} instead of just 'Database Error: Failed to Create Invoice.'

Summary, no need to add any return types but fix the try/catch to return what it should return in the new implementation.

Copy paste the code-block from https://nextjs.org/learn/dashboard-app/improving-accessibility without any changes and type errors should be gone. Also same code below:

export async function createInvoice(prevState: State, formData: FormData) {
  // Validate form using Zod
  const validatedFields = CreateInvoice.safeParse({
    customerId: formData.get('customerId'),
    amount: formData.get('amount'),
    status: formData.get('status')
  });

  // If form validation fails, return errors early. Otherwise, continue.
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Create Invoice.'
    };
  }

  // Prepare data for insertion into the database
  const { customerId, amount, status } = validatedFields.data;
  const amountInCents = amount * 100;
  const date = new Date().toISOString().split('T')[0];

  // Insert data into the database
  try {
    await sql`
      INSERT INTO invoices (customer_id, amount, status, date)
      VALUES (${customerId}, ${amountInCents}, ${status}, ${date})
    `;
  } catch (error) {
    // If a database error occurs, return a more specific error.
    return {
      message: 'Database Error: Failed to Create Invoice.'
    };
  }

  // Revalidate the cache for the invoices page and redirect the user.
  revalidatePath('/dashboard/invoices');
  redirect('/dashboard/invoices');
}

o-ja avatar Dec 08 '23 20:12 o-ja

@nemchik, I ran into same issue but the issue actually was that I didn't fully change the createInvoice. In sql try/catch block the earlier version returns string when error but it should return { message: 'Database Error: Failed to Create Invoice.'} instead of just 'Database Error: Failed to Create Invoice.'

Summary, no need to add any return types but fix the try/catch to return what it should return in the new implementation.

Copy paste the code-block from https://nextjs.org/learn/dashboard-app/improving-accessibility without any changes and type errors should be gone. Also same code below:

export async function createInvoice(prevState: State, formData: FormData) {
  // Validate form using Zod
  const validatedFields = CreateInvoice.safeParse({
    customerId: formData.get('customerId'),
    amount: formData.get('amount'),
    status: formData.get('status')
  });

  // If form validation fails, return errors early. Otherwise, continue.
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Create Invoice.'
    };
  }

  // Prepare data for insertion into the database
  const { customerId, amount, status } = validatedFields.data;
  const amountInCents = amount * 100;
  const date = new Date().toISOString().split('T')[0];

  // Insert data into the database
  try {
    await sql`
      INSERT INTO invoices (customer_id, amount, status, date)
      VALUES (${customerId}, ${amountInCents}, ${status}, ${date})
    `;
  } catch (error) {
    // If a database error occurs, return a more specific error.
    return {
      message: 'Database Error: Failed to Create Invoice.'
    };
  }

  // Revalidate the cache for the invoices page and redirect the user.
  revalidatePath('/dashboard/invoices');
  redirect('/dashboard/invoices');
}

The only difference between the code you posted there and what i am suggesting is

export async function createInvoice(prevState: State, formData: FormData) {

vs

export async function createInvoice(
  prevState: State,
  formData: FormData,
): Promise<State> {

When removing the return type on the function I get an error in app/ui/invoices/create-form.tsx on line 17 https://github.com/vercel/next-learn/blob/e75f71499fd2bc2dbabf60992f423e07d33c15fd/dashboard/final-example/app/ui/invoices/create-form.tsx#L17 image The tooltip in the screenshot scrolls, but the contents are essentially what I posted in my original message. this is also the same output I get when running npm run build.

nemchik avatar Dec 08 '23 21:12 nemchik

Got the same problem when I reached chapter 14. At first I tried your solution but didn't work. When I checked the integrity of my app/ui/invoices/create-form.tsx file, I found that I had a typo like the following:

create-form.tsx with typo

// imports ...

export default function Form({ customers }: { customers: CustomerField[] }) {
  const initialState = { mesasage: null, error: {} } // <- ** Typo here! Should be "errors", not "error" **
  const [state, dispatch] = useFormState(createInvoice, initialState)

  return (
    <form action={dispatch}>...</form>
  )

create-form.tsx fixed ✅

// imports ...

export default function Form({ customers }: { customers: CustomerField[] }) {
  const initialState = { mesasage: null, errors: {} } // <- ** Typo fixed **

// ...

This fixed the type error that you showed, the same I had. No need to add types into either createInvoice or updateInvoice from app/lib/actions.ts.

CesarQD98 avatar Feb 19 '24 23:02 CesarQD98

Got the same problem when I reached chapter 14. At first I tried your solution but didn't work. When I checked the integrity of my app/ui/invoices/create-form.tsx file, I found that I had a typo like the following:

create-form.tsx with typo

// imports ...

export default function Form({ customers }: { customers: CustomerField[] }) {
  const initialState = { mesasage: null, error: {} } // <- ** Typo here! Should be "errors", not "error" **
  const [state, dispatch] = useFormState(createInvoice, initialState)

  return (
    <form action={dispatch}>...</form>
  )

create-form.tsx fixed ✅

// imports ...

export default function Form({ customers }: { customers: CustomerField[] }) {
  const initialState = { mesasage: null, errors: {} } // <- ** Typo fixed **

// ...

This fixed the type error that you showed, the same I had. No need to add types into either createInvoice or updateInvoice from app/lib/actions.ts.

I do not have this spelling error. I tested again today removing the type (: Promise<State>) and it continues to cause the error I posted above.

nemchik avatar Feb 20 '24 01:02 nemchik

What's the fix?

Marini83 avatar Mar 05 '24 17:03 Marini83

It appears there has not yet been a fix.

nemchik avatar Mar 13 '24 13:03 nemchik

Yeah im getting the same issue. Error is solely around the useFormState in the edit-form.tsx. It doesn't throw a runtime error. The Create Invoice button does nothing and there are no Aria warnings for amount or status in the invoice. Although the Customer Name warning works ok.

paulreedaus avatar Apr 15 '24 12:04 paulreedaus

Actually to fix my problem I just found I was missing an import statement at the top of the code.

import { useFormState } from 'react-dom';

paulreedaus avatar Apr 20 '24 00:04 paulreedaus

I'm not missing the import, still have the issue.

nemchik avatar Apr 20 '24 02:04 nemchik

Update: I am in the same situation. Compile correctly but the error is there.

stabla avatar Apr 25 '24 15:04 stabla

Hello. I am not following this course but I am having exactly the same issue in a personal project. Any fixes found?

brenoos avatar May 29 '24 19:05 brenoos

Ok, I found a solution for my case, not sure if it's the same that you guys were seeing.

After revalidatePath I needed a return setting errors and message.

  revalidatePath('/home/sessions/add');

  return { errors: {}, messages: 'User created' };

or using a redirect.

  revalidatePath('/home/sessions/add');

  redirect("/home")

If you have a try catch block for your data mutation, you need the return in both cases, inside the try block and inside the catch block

brenoos avatar May 29 '24 20:05 brenoos

The TypeScript error in app/ui/invoices/create-form.tsx can be fixed by replacing the null value for the message property in initialState with an empty string ''

const initialState = { message: '', error: {} };
const [state, dispatch] = useFormState(createInvoice, initialState);

marcosarce avatar May 30 '24 04:05 marcosarce

The TypeScript error in app/ui/invoices/create-form.tsx can be fixed by replacing the null value for the message property in initialState with an empty string ''

const initialState = { message: '', error: {} };
const [state, dispatch] = useFormState(createInvoice, initialState);

This is the first solution anyone has posted that actually worked for me. I'm kind of shocked that this is what made it work, and also shocked that this issue has remained open for so long.

nemchik avatar May 30 '24 12:05 nemchik

can be fixed by replacing the null value for the message property in initialState with an empty string ''

message values can be a string | null as we are setting the State type in actions.ts.

next_issue_rathore

referencing an issue here

Thank you.

GaneshSrambikal avatar May 31 '24 12:05 GaneshSrambikal

useFormState

Thank you for this context! This actually makes it make more sense, but there's still an error thrown when using

const initialState = { message: null, errors: {} };

However this is actually fixed by using

import { type State } from '@/app/lib/actions';
...
const initialState: State = { message: null, errors: {} };

Doing this in both create-form.tsx and edit-form.tsx resolves the error being thrown without needing to define the Promise<State> return type on the createInvoice or updateInvoice functions, or having to use an empty string for the message.

nemchik avatar May 31 '24 19:05 nemchik

However this is actually fixed by using

Yes, That works too.

I have followed every instruction from Chapter 1 to Chapter 16 in this tutorial and bumped into small errors but completed the tutorial. Here is the Final Live Demo Codes : GaneshSrambikal/nextjs_from_offical

This is my package.json:

{
  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next dev",
    "prettier": "prettier --write --ignore-unknown .",
    "prettier:check": "prettier --check --ignore-unknown .",
    "start": "next start",
    "seed": "node -r dotenv/config ./scripts/seed.js",
    "lint": "next lint"
  },
  "dependencies": {
    "@heroicons/react": "^2.0.18",
    "@tailwindcss/forms": "^0.5.7",
    "@types/node": "20.5.7",
    "@vercel/postgres": "^0.5.1",
    "autoprefixer": "10.4.15",
    "babel": "^6.23.0",
    "bcrypt": "^5.1.1",
    "clsx": "^2.0.0",
    "next": "^14.0.2",
    "next-auth": "^5.0.0-beta.18",
    "postcss": "8.4.31",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.3",
    "typescript": "5.2.2",
    "use-debounce": "^10.0.0",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@types/bcrypt": "^5.0.1",
    "@types/react": "18.2.21",
    "@types/react-dom": "18.2.14",
    "@vercel/style-guide": "^5.0.1",
    "dotenv": "^16.3.1",
    "eslint": "^8.52.0",
    "eslint-config-next": "^14.0.0",
    "eslint-config-prettier": "9.0.0",
    "prettier": "^3.0.3",
    "prettier-plugin-tailwindcss": "0.5.4"
  },
  "engines": {
    "node": ">=18.17.0"
  }
}

GaneshSrambikal avatar Jun 01 '24 11:06 GaneshSrambikal

Here's my package.json

{
  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next dev",
    "lint": "next lint",
    "prettier": "prettier --write --ignore-unknown .",
    "prettier:check": "prettier --check --ignore-unknown .",
    "seed": "node -r dotenv/config ./scripts/seed.js",
    "start": "next start"
  },
  "dependencies": {
    "@heroicons/react": "^2.1.3",
    "@tailwindcss/forms": "^0.5.7",
    "@types/node": "^20.12.11",
    "@vercel/postgres": "^0.8.0",
    "autoprefixer": "^10.4.19",
    "bcrypt": "^5.1.1",
    "clsx": "^2.1.1",
    "next": "^14.2.3",
    "next-auth": "^5.0.0-beta.17",
    "postcss": "^8.4.38",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "tailwindcss": "^3.4.3",
    "typescript": "^5.4.5",
    "use-debounce": "^10.0.0",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@types/bcrypt": "5.0.2",
    "@types/react": "18.3.3",
    "@types/react-dom": "18.3.0",
    "@vercel/style-guide": "6.0.0",
    "dotenv": "16.4.5",
    "eslint": "8.57.0",
    "eslint-config-next": "14.2.3",
    "eslint-config-prettier": "9.1.0",
    "prettier": "3.2.5",
    "prettier-plugin-tailwindcss": "0.5.14"
  },
  "engines": {
    "node": "20.x",
    "npm": "10.x"
  }
}

I do have some different package versions. Mostly it's been updated by renovate bot for me. Also I notice you have babel and I do not, and nor does https://github.com/vercel/next-learn/blob/b7a4366f682163a6643416c9cdf2d9c43d0fc542/dashboard/final-example/package.json

The issue is mostly noticeable in vscode, before even deploying anything to vercel.

nemchik avatar Jun 01 '24 17:06 nemchik

Hi I ran into the same issue but my case is a bit different. I don't use injected SQL in the createInvoice function but call an API since I built my own server. I tried everything this thread suggested:

  • changed null to '' in const initialState = { message: null, errors: {} };
  • added Promise<State>
  • added return { message: 'Database Error: Failed to Create Invoice.'}
  • checked type in const initialState = { message: null, errors: {} }; and confirmed I wrote errors with s, not error
  • checked import and already import useFormState
  • tried const initialState: State = { message: null, errors: {} };
  • confirmed message is string | null NOTHING worked. Really frustrated...

It's weird that I had no problem following the tutorial. At first I did see this error but when I pasted all the code in the tutorial, the issue went away. But when I applied the code to my own project (which is just like the code in the tutorial), I got stuck in this error and couldn't find any fix or understand why it happened. Here's my code. I really appreciate if anyone can come up with a solution.

create-order.tsx (it is create-form.tsx in the tutorial)

"use client";

import Link from "next/link";
import {
  CheckIcon,
  ClockIcon,
  CurrencyDollarIcon,
  UserCircleIcon,
} from "@heroicons/react/24/outline";
import { Button } from "@/app/ui/buttons";
import { createInvoice } from "@/app/lib/actions";
import { useFormState } from "react-dom";
import { type State } from "@/app/lib/actions";
export default function Form() {
  const initialState: State = { message: null, errors: {} };
  const [state, dispatch] = useFormState(createInvoice, initialState);

  return (
    <form action={dispatch}>
      <div className="rounded-md bg-gray-50 p-4 md:p-6">
....

actions.ts

export type OrderState = {
  errors?: {
    amount?: string[];
    status?: string[];
  };
  message?: string | null;
};

export async function createInvoice(prevState: OrderState, formData: FormData) {
  // Validate form fields using Zod
  const validatedFields = CreateOrder.safeParse({
    amount: formData.get('amount'),
    status: formData.get('status'),
  });

  // If form validation fails, return errors early. Otherwise, continue.
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Create Invoice.',
    };
  }

  validatedFields.data.amount *= 100;
  const orderData = validatedFields.data;

  try {
    const response = await fetch(
      "http://localhost:4000/dashboard/order/new",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify(orderData),
      }
    );
    console.log(response);

    if (!response.ok) {
      throw new Error("Faile to create new order");
    }

    const responseData = await response.json();
    console.log(responseData);
    if (!responseData || !responseData.product || !responseData.product._id) {
      throw new Error(
        "No response data or no responseData.product or no responseData.product._id"
      );
    }
    
    console.log("Order created successfully", responseData);
  } catch (error) {
    return {
      message: 'Database Error: Failed to Create Product.'
    };
  }

  // Revalidate the cache for the invoices page and redirect the user.
  // revalidatePath('/dashboard/invoices');
  // redirect('/dashboard/invoices');
}

octopus198 avatar Jun 05 '24 16:06 octopus198

Hi I ran into the same issue but my case is a bit different. I don't use injected SQL in the createInvoice function but call an API since I built my own server. I tried everything this thread suggested:

  • changed null to '' in const initialState = { message: null, errors: {} };
  • added Promise
  • added return { message: 'Database Error: Failed to Create Invoice.'}
  • checked type in const initialState = { message: null, errors: {} }; and confirmed I wrote errors with s, not error
  • checked import and already import useFormState
  • tried const initialState: State = { message: null, errors: {} };
  • confirmed message is string | null NOTHING worked. Really frustrated...

It's weird that I had no problem following the tutorial. At first I did see this error but when I pasted all the code in the tutorial, the issue went away. But when I applied the code to my own project (which is just like the code in the tutorial), I got stuck in this error and couldn't find any fix or understand why it happened. Here's my code. I really appreciate if anyone can come up with a solution.

create-order.tsx (it is create-form.tsx in the tutorial)

"use client";

import Link from "next/link";
import {
  CheckIcon,
  ClockIcon,
  CurrencyDollarIcon,
  UserCircleIcon,
} from "@heroicons/react/24/outline";
import { Button } from "@/app/ui/buttons";
import { createInvoice } from "@/app/lib/actions";
import { useFormState } from "react-dom";
import { type State } from "@/app/lib/actions";
export default function Form() {
  const initialState: State = { message: null, errors: {} };
  const [state, dispatch] = useFormState(createInvoice, initialState);

  return (
    <form action={dispatch}>
      <div className="rounded-md bg-gray-50 p-4 md:p-6">
....

actions.ts

export type OrderState = {
  errors?: {
    amount?: string[];
    status?: string[];
  };
  message?: string | null;
};

export async function createInvoice(prevState: OrderState, formData: FormData) {
  // Validate form fields using Zod
  const validatedFields = CreateOrder.safeParse({
    amount: formData.get('amount'),
    status: formData.get('status'),
  });

  // If form validation fails, return errors early. Otherwise, continue.
  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: 'Missing Fields. Failed to Create Invoice.',
    };
  }

  validatedFields.data.amount *= 100;
  const orderData = validatedFields.data;

  try {
    const response = await fetch(
      "http://localhost:4000/dashboard/order/new",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify(orderData),
      }
    );
    console.log(response);

    if (!response.ok) {
      throw new Error("Faile to create new order");
    }

    const responseData = await response.json();
    console.log(responseData);
    if (!responseData || !responseData.product || !responseData.product._id) {
      throw new Error(
        "No response data or no responseData.product or no responseData.product._id"
      );
    }
    
    console.log("Order created successfully", responseData);
  } catch (error) {
    return {
      message: 'Database Error: Failed to Create Product.'
    };
  }

  // Revalidate the cache for the invoices page and redirect the user.
  // revalidatePath('/dashboard/invoices');
  // redirect('/dashboard/invoices');
}

Hey, As per your code mentioned above, there are two mistakes you made which can be fixed:

  1. In Create-form.tsx( in your case create-order.tsx ) const initialState: State = { message: null, errors: {} }; Here you are defining type of initialState as State which is not needed. You can fix this by replacing it with this const initialState = { message: null, errors: {} };

  2. In Create-form.tsx( in your case create-order.tsx ) there are missing parameters in Form function which is { customers }: { customers: CustomerField[] }

I Hope this fixes your code. Happy coding Thank you.

GaneshSrambikal avatar Jun 08 '24 19:06 GaneshSrambikal

Hey, As per your code mentioned above, there are two mistakes you made which can be fixed:

  1. In Create-form.tsx( in your case create-order.tsx ) const initialState: State = { message: null, errors: {} }; Here you are defining type of initialState as State which is not needed. You can fix this by replacing it with this const initialState = { message: null, errors: {} };
  2. In Create-form.tsx( in your case create-order.tsx ) there are missing parameters in Form function which is { customers }: { customers: CustomerField[] }

I Hope this fixes your code. Happy coding Thank you.

Thanks for your comment. Regarding the parameter { customers }: { customers: CustomerField[] }, I intentionally left it out because in my project, I don't need such data. Anyway, I managed to fix the error No overload matches this call. But now, I run into another issue, which is Property 'errors' does not exist on type '{ message: string; }'.ts(2339). Even though I have declared both message and errors in the initialState variable.

const initialState = { message: "", errors: {} };
  const [state, dispatch] = useActionState(createProduct, initialState); 
Screenshot 2024-06-11 at 22 14 18

octopus198 avatar Jun 11 '24 15:06 octopus198