TheEdoRan / next-safe-action

Type safe and validated Server Actions in your Next.js project.
https://next-safe-action.dev
MIT License
2.29k stars 35 forks source link

[BUG] #223

Closed littlechad closed 3 months ago

littlechad commented 3 months ago

Are you using the latest version of this library?

Is there an existing issue for this?

Describe the bug

Got Error: A "use server" file can only export async functions, found object. when submitting using the execute method. And i can confirm that the same code is working on v6

Reproduction steps

  1. create the following server actions
'use server'

import { createSafeActionClient } from 'next-safe-action'

import { schema } from './schema'

export const action = createSafeActionClient()

export const report = action
  .schema(schema)
  .action(async ({ parsedInput: values }) => {
    try {
      schema.parse(values)

      const { result, error } = await create({ values }) // insert to db
      if (!result && error) {
        throw new Error(error.message)
      }

      return result
    } catch (e) {
      console.log('e: ', e)
      return e
    }
  })
  1. create the following client component
'use client'

...
import { useAction } from 'next-safe-action/hooks'
...

import { report } from './actions'
import { schema } from './schema'
...

function Component({ allow, selecteds, setSelecteds }: Props) {
  ...

  const { execute, status, hasErrored } = useAction(report, {
    onSuccess() {
      console.log('execute onSuccess: ')
    },
    onExecute() {
      console.log('execute onExecute: ')
    },
    onError({ error }) {
      console.log('execute onError: ', error)
    },
  })

  const onSubmit = (values: z.infer<typeof schema>) => {
    console.log('values: ', values)
    execute(values)
  }

  console.log('hasErrored: ', hasErrored)

  return (
    <>
      ...
        <Form {...form}>
          <form onSubmit={form.handleSubmit(onSubmit)}>
            ...
              <Button type="submit" className="flex space-x-2 px-3" disabled={status === 'executing'}>
                {(status === 'executing') && (<div className="border-gray-300 mr-2 h-5 w-5 animate-spin rounded-full border-4 border-t-primary" />)}
                <File className="h-4 w-4" />
                <span>Report</span>
              </Button>
           ...
          </form>
        </Form>
      </>
  )
}

export default Component

Expected behavior

Form got sumbitted and data got inserted to the db

Minimal reproduction example

-

Operating System

node:lts-alpine

Library version

^7.4.3

Next.js version

14

Additional context

No response

TheEdoRan commented 3 months ago

Seems to be a duplicate of #70. The action client should be placed in a different file (like lib/safe-action.ts) without the "use server" directive, as explained in the docs. "use server" is just needed for files where you declare Server Actions. If this doesn't solve the problem, please provide a link to a repo with a minimal reproduction of the issue, thanks.

littlechad commented 3 months ago

Ah, you're right, after placing the client on a different file it works, thanks!