Contact Form Without a Server Using Angular
Do you ever need a contact form for your personal website, but don’t want to have to setup a backend server, use SendGrid, Mailchimp, Formspree, to send only a few emails a day? Look no further, you can send emails and log them in a Google Spreadsheet without having to spend any money or time managing, deploying, and creating a backend server.
Overview
In this tutorial, we will be going through the following concepts:
- Creating our Google service to send emails
- Angular Reactive Forms
- Form creation using HTML and CSS and data binding
Pre-requisites
To follow along, you will need to have NodeJS and Angular CLI installed on your computer, and a Google account to send emails.
Creating your Google service to send emails
This was made by using Send Email from a Static HTML Form using Google Apps Mail! repository which goes through the full details on implementing this onto your Google account. Full credit goes to the developers that worked on the project.
- Start by making a copy of this spreadsheet using your Google Account.
- Open the Script Editor by clicking “Tools” > “Script Editor”
- Uncomment the
TO_ADDRESS
field and changeexample@email.net
to your email - Save it by clicking “File” > “Manage versions” and typing in a version name
- Publish it as a web application by clicking “Publish” > “Deploy as web app…” and select the latest project version
- Authorize the application and copy the web application URL
Now that you’re done setting up the script that will handle all the submissions, we can start by creating a form to utilize our created script.
Create a new Angular App and a component
Creating a new Angular application is quite easy using the Angular CLI. Start by opening the Command Prompt or Terminal and creating the application using the Angular CLI. After the application has been created, generate a component (in this case our contact component) to put our forms into. We will be using the Material theme to style our form:
ng new angular-application
> any of the options are fine
cd angular-application
ng g component contact
ng add @angular/material
> any of the options are fine
ng serve
After creating your new Angular application and component, you’ll have a folder structure like this:
After calling ng serve
, you can go to localhost:4200 to access your application and you’ll be welcomed with a welcome page:
To show our contact component, replace all the existing code in app.component.html
with <app-contact></app-contact>
. That special element is not in HTML, it is defined in your contact component which renders its contents. We will be updating the component soon. After doing so, your application will look like this:
Angular Reactive Forms
Angular Reactive Forms use explicit and an immutable approach to managing the state of a form at a given point in time
To get started with Reactive Forms and make HTTP requests in our Angular application, we’ll need to import the ReactiveFormsModule
from the @angular/forms
package and HttpClientModule
from the @angular/common/http
package and add it to the import
array in the@NgModule
decorator in app.module.ts
like so:
After doing so, we can use the HttpClient
to send requests to the Google web application and the FormBuilder
to create the controls for our form, validate, and manage our form. Start by importing FormBuilder
from @angular/forms
and HttpClient
from @angular/common/http
. After doing so, we inject both of them into our constructor
in contact.component.ts
like so:
After doing that, we’ll need to create the a form
property to bind our HTML form to, the form controls, and provide some validators for the inputs. To do this, we’ll need to also import FormGroup, FormControl, Validators
from @angular/forms
like so:
We can now add a method that will validate the form and send a POST
request to the Google web application URL that we created earlier. To do so, we will need an onSubmit
method that also checks if the form is valid before submission. We can do this by accessing this.form.status
which returns VALID
if the form is valid and this.honeypot.value == “”
to make sure the honeypot is empty. To provide some better design, we’ll let the user know that we’re loading by setting this.isLoading
and disabling/enabling the form on its state using this.form.disable()
and this.form.enable()
respectively.
Here is the final code snippet
Form creation using HTML and CSS and data binding
That’s all the functionality of the form submission and validation done. We can now create the HTML and CSS form that will be shown to the users. You can style the form however you’d like, but in this tutorial, we will be using Angular Material.
The CSS will be very basic. I’ve written down some classes to hide the success message before submission and show it after a successful submission. I’ve also added some margin
on the fields so they aren’t directly next to each other:
For the HTML form, we’ll need to create the <form>
tag with attribute method="post"
which groups all of our inputs. This uses the [formGroup]
property which is bound to the form
in contact.component.ts
. We’ll also need to bind the form controls that we’ve defined in contact.component.ts
by using the [formControl]
property on the input
tags. For the onSubmit
method that we wrote earlier, we also need to bind it to the (ngSubmit)
event which is run when we click the <button>
to submit. Here is the basic form HTML and what it looks like without any Material styling (this has no hints or error messaging for the user, but you can add those as desired):
Here is the form HTML and what it looks like after applying some Material styling using the same base form HTML (this includes hints and error messaging for the user so that they know what needs to be changed to successfully send it):
That’s all! You can go back to localhost:4200, fill in the form and submit it. You will see an email was sent to the designated inbox and a row in your Google Spreadsheet is filled in with your form values. Thank you guys for so much for reading! If you have any questions, maybe you can update the TO_ADDRESS
and send me a contact 😛
If you want the full source code, you can access the repo here on Github.