Homepage

Handling Valid Input

Last edit: Oct 21, 2024

When the user submits valid input through the Contact Us form, we need to perform a few actions:

  1. Store the contact data in the database.
  2. Send a confirmation email to the user (a simple static confirmation that their request was received.)
  3. Redirect the user to /contacts/thanks and display a simple “Thank you” message.

Store the Contact Details in the Database

To store contact requests in the database, we are using the contact.yml table created in the Setting Up a Schema step.

With the schema in place, the necessary actions were integrated into the application. The goal was to validate the contact form and persist the valid data in the database. To achieve this, we created a GraphQL mutation in the app/graphql/contacts/create.graphql file during the Saving Data in the Database step to persist the contact data. This mutation is now used to store the contact data in the database!

Create execute.liquid file

First, create the execute.liquid file in the following directory:

 app/lib/commands/contacts/create/execute.liquid

To populate it, you don’t have to write the execute command from scratch. Instead, let's refer to the core module documentation’s Execute section. Here's the example execute command you can use:

{% liquid
  graphql r = 'dummy/create', args: object

  assign object = r.record_create
  hash_assign object['valid'] = true

  return object
%}

Copy the code above from the core module documentation and paste it into your execute.liquid file. Make the following modifications:

app/lib/commands/contacts/create/execute.liquid

{% liquid
  graphql r = 'contacts/create', args: object

  assign object = r.record_create
  hash_assign object['valid'] = true

  return object
%}

This command executes a GraphQL mutation to persist the data and prepares the object for further validation. Let’s break it down:

 graphql r = 'contacts/create', args: object

This line uses the graphql tag to execute a GraphQL mutation. The mutation is named contacts/create, and it takes object as an argument.

assign object = r.record_create

This line assigns the result of the mutation to the object variable.

hash_assign object['valid'] = true

This line artificially assigns the valid property of the object to true. This is done for consistency, as this property will be used in the check command.

Invoke the execute command in the create.liquid file

Now that we have the execute command set up, we need to invoke this command within our main create.liquid file to handle the form submission process. Our goal is to ensure that the execute command is properly called after the build and check commands validate the contact data.

Modify your app/lib/commands/contacts/create.liquid file:

app/lib/commands/contacts/create.liquid

{% function contact = 'commands/contacts/create/build', object: object %}
{% function contact_after_validation = 'commands/contacts/create/check', object: contact %}

{% if contact_after_validation.valid %}
    {% function contact_after_execute = 'commands/contacts/create/execute', object: contact_after_validation %}
{% endif %}

{% return contact_after_execute %}

Let’s see what we do here:

{% function contact = 'commands/contacts/create/build', object: object %}

This line invokes the build command, passing the object (the form data). The result is assigned to the contact variable.

{% function contact_after_validation = 'commands/contacts/create/check', object: contact %}

This line invokes the check command with the contact object. The result is assigned to the contact_after_validation variable.

As you notice, we added a conditional execute command invocation:

{% if contact_after_validation.valid %}
    {% function contact_after_execute = 'commands/contacts/create/execute', object: contact_after_validation %}
{% endif %}

If the contact_after_validation object is valid, the execute command is invoked, passing the validated contact object. The result is assigned to the contact_after_execute variable.

{% return contact_after_execute %}

Then the final result after execution is returned.

If you try it, the invalidation won't work correctly. For valid inputs, when the user submits the form, everything will function as expected. However, for invalid inputs, the system will still attempt to return contact_after_execute even though it hasn't reached that point because contact_after_validation.valid is false in this scenario. This means we'll end up returning null, which results in losing information about validation error messages and the original user input.

A way to fix it would be by returning the correct variable if valid is false:

{% if contact_after_validation.valid %}
    {% function contact_after_execute = 'commands/contacts/create/execute', object: contact_after_validation %}
    {% return contact_after_execute %}
{% else %}
    {% return contact_after_validation %}
{% endif %}

Instead of these solutions, let’s rename everything to object:

app/lib/commands/contacts/create.liquid

{% function object = 'commands/contacts/create/build', object: object %}
{% function object = 'commands/contacts/create/check', object: object %}

{% if object.valid %}
    {% function object = 'commands/contacts/create/execute', object: object %}
{% endif %}
   
{% return object %}

Special arguments: args

In the context of platformOS, the args parameter serves as a special argument that can be either a hash or a string of arguments passed to the GraphQL query.

When passing multiple arguments at once, you can encapsulate them within a JSON string. For example:

{% capture arguments %}
{
  "per_page": 20,
  "page": 2
}
{% endcapture %}

{% graphql g = "get_models", args: arguments %}

Without using args, you would need to specify each argument individually like this:

{% graphql g = "get_models", page: 2, per_page: 20 %}

While for a small number of arguments, this may not seem particularly beneficial, it becomes more advantageous when dealing with a larger number of arguments, such as 10 or 20.

To learn more about how args function, refer to the examples provided in the Liquid Tags chapter of the documentation.

Questions?

We are always happy to help with any questions you may have.

contact us