Nuxt - Laravel Precognition
GitHubNuxt Module
  • Getting Started
    • Introduction
    • Installation
  • Usage
    • Configuration
  • Validation
  • Error handling
  • File uploads
  • Use with Nuxt UI
  • Composables
    • usePrecognitionForm
    • usePrecognitionConfig
    • useNuxtFormValidator
  • Other
    • Breeze Nuxt template
    • Troubleshooting
Powered by GitBook
On this page
  • Form data
  • Fields
  • Data
  • Reset
  • Errors
  • State
  • Validation
  • Submit form
  1. Composables

usePrecognitionForm

Composable for working with Precognition form instance in your code.

This composable is used to create an instance of a Precognition form that supports both validation and data submission.

We use a type system so you can work with only existing properties of the object. You have to define a Type of Interface for your payload.

Here is a basic sample of form creation:

type MyFormType = {
  email: string
  password: string
}

const form = usePrecognitionForm<MyFormType>(
  'post',
  '/api/signup',
  {
    email: '',
    password: '',
  },
)

Form data

Fields

You can easily access each field of the form by accessing form.fields.NAME where NAME is a key of your form schema.

<input
  id="password"
  v-model="form.fields.password"
  type="password"
  @change="form.validate('password')"
>

In case you need the whole payload as a reactive object, you can use just form.fields value, which returns the complete state.

console.log('Form fields:', form.fields)

Data

To get the value underneath the reactive wrapper, just use form.data() method, which is also used for form submission under the hood.

const myFormData = form.data()

Since some values may be updated programmatically, you can rely on setData method to set multiple values at once instead of working with reactive fields value.

const newDataToAssign = { password: 'random-string' }

form.setData(newDataToAssign)

This keeps existing values and overrides only new keys passed as an argument.

Reset

You can always reset the form or a single field to the original state, which was passed as an argument to usePrecognitionForm composable.

const form = usePrecognitionForm<MyFormType>(
  'post',
  '/api/signup',
  {
    email: 'john@doe.com',
    password: '',
  },
)

form.setData({ email: 'jane@doe.com' })
console.log(form.fields.email) // jane@doe.com

form.fields.email = 'invalid@email.com'
console.log(form.fields.email) // invalid@email.com

form.reset('email')
console.log(form.fields.email) // john@doe.com

form.reset() // resets all form fields

Errors

Our module takes care of the form error propagation once we have a response from the Laravel API. However, the method of their representation depends on your specific needs.

To retrieve the current state of errors, you may use form.errors reactive value:

form.validate()
const errors = form.errors

It returns a Record<string, string[]> map where each field name contains multiple error messages returned from the API.

You can also check if there are any errors at all by checking the value of form.hasErrors, which is useful for Vue templates:

<div v-if="form.hasErrors">
  <!-- Show errors here -->
</div>

In case you need to reset some errors before it gets validated, use forgetError helper method:

<input
    id="avatar"
    type="file"
    @change="(e) => {
        form.avatar = e.target.files[0]
        form.forgetError('avatar')
    }"
>

Behind the scenes, our module uses setErrors method to update the form state according to the API response, but you can easily use it in your code as well:

const myErrorsToSet = {
  email: [
    'Email should contain only one "@" character',
    'Email should not contain spaces',
  ],
  password: ['You cannot use emojis in the password'], 
}

form.setErrors(myErrorsToSet)

State

While working with a form, you can get the current state details by using processing and validating fields. Both values are stored as Ref<boolean> type.

  • Processing equals true if your submit request is in flight state (being sent to the API).

  • Validating equals true if your validation request is in flight state.

These states are useful if you want to disable Submit/Validate buttons to avoid multiple requests against the API.

<button
  :disabled="form.processing"
  @click="submit"
>
  Submit
</button>

<button
  :disabled="form.validating"
  @click="validate"
>
  Validate
</button>

Validation

The precognition form has the same method to validate a particular field or the whole form at once. Here is an example:

form.validate('email') // validates only email
form.validate(['email', 'password']) // validates both fields

This might be useful if you have a single form separated into several steps (e.g. Installation Wizards, Multi-Stage Signup, etc).

<button
    type="button"
    @click="form.validate(
        ['name', 'email', 'phone'], 
        {
            validateFiles: false,
            onSuccess: (response: FetchResponse<unknown>) => /* ... */,
            onError: (error) => /* ... */,
            onValidationError: (response: FetchResponse<unknown>) => /* ... */,
        }
    )"
>
    Next Step
</button>

As you can see in the example above, we also pass an additional argument to validate method, which contains the following:

  • validateFiles - flag determines whether we should attach files to validate via API

  • onSuccess(response: FetchResponse<unknown>) - callback to execute on successful validation response

  • onError(error: Error | FetchResponse<unknown>) - callback to handle any error thrown by either API or Nuxt itself

  • onValidationError(response: FetchResponse<unknown>) - callback to handle validation errors only; it will be executed after form errors are propagated

You may want to check a particular field validation state, and there are two simple methods for that:

  • form.valid(fieldName) - returns true if field is valid and there are no errors

  • form.invalid(fieldName) - returns true if field is invalid or has not been validated yet

<div v-if="form.invalid('email')">
  Error: {{ form.errors.email }}
</div>

Submit form

Once you have all fields validated and ready to be sent to the Laravel API, you should use submit method.

If you prefer callback-style syntax, feel free to use submit as a Promise:

form
  .submit()
  .then((response: FetchResponse<unknown>) => console.log('Form submitted', response))
  .catch((error: FetchResponse<unknown>) => console.error('Form error', error))

But if you prefer async-await syntax, here is the same behaviour:

try {
  const response = await form.submit()
  console.log('Form submitted', response)
}
catch (e) {
  const response = e as FetchResponse<unknown>
  console.error('Form error', response)
}

Now you are ready to use Laravel Precognition with Nuxt! 🚀

PreviousUse with Nuxt UINextusePrecognitionConfig

Last updated 2 months ago