In the previous chapter, we created a route handler to serve a sign up form. We also created the Selmer HTML template for this form, and as of now, it renders and looks pretty when we hit http://localhost:3000/signup
. In this chapter, we're going to take it a bit further by:
There are typically three things we need to do when handling form input: validate the input, show an error message if the input is invalid, and show a success message when the input is valid and accepted.
In order for us to validate the form input, we need to create a route where the form will POST. We made a number of these in the previous chapter, so we'll draw on that experience and pattern.
Let's create a new route for the same URL, /signup
, but this time we'll ensure that it accepts a POST
request instead of a GET
request. We'll put it along with the existing /signup
GET
route in our hipstr.routes.home
namespace:
(defroutes home-routes
(GET "/" [] (home-page))
(GET "/about" [] (about-page))
(GET "/signup" [] (signup-page))
(POST "/signup" [& form] (str "nice job"))
We now have two routes for the same URL, one that will handle the GET
request, and another that will handle the POST
request. You'll notice that GET
doesn't care about any parameters, however, POST
uses Compojure's get the rest of the request map parameters destructuring syntax. This is just a bit of semantic sugar so that it's clear that we're working with just the values posted from the form instead of the entire request map.
That being said, the POST
route doesn't do a whole lot for us at this point other than giving us a slightly sarcastic "nice job". Let's create a function similar to the existing hipstr.routes.home/signup-page
function to handle the POST /signup
response.
First, we need to make use of the ring.util.response
namespace, as it has a function to issue a response redirect, which we can use to redirect the user to a sign up success page. Add the following to the hipster.routes.home
namespace's :require
key:
[ring.util.response :as response]
Next, we'll write the function to determine the appropriate response:
(defn signup-page-submit [user] #_(let [errors (signup/validate-signup user)] (if (empty? errors) (response/redirect "/signup-success") (layout/render "signup.html" (assoc user :errors errors)))))
In the preceding function, we validate the form using the hipstr.signup
namespace (which we'll create next) and then, if successful, redirect the user to a sign up success page; otherwise, we repopulate the form and display the validation errors.
Before we create the hipstr.signup
namespace, let's quickly change our route handler to make use of the signup-page-submit
function and add a route for the success page:
(defroutes home-routes (GET "/" [] (home-page)) (GET "/about" [] (about-page)) (GET "/signup" [] (signup-page)) (POST "/signup" [& form] (signup-page-submit form)) (GET "/signup-success" [] "Success!"))
18.188.57.172