Handling Valid Input
When the user submits valid input through the Contact Us form, we need to perform a few actions:
- Store the contact data in the database.
- Send a confirmation email to the user (a simple static confirmation that their request was received.)
- 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.