Angular basics:
- Services
- TemplateForms
- Let's assume that you already initialized your app and you have your component that has the form.
- Create a service (mail)
ng generate service services/mail- define a method called (sendEmail()) that will return a Promise and accept a parameter (formData) that has type of (FormData).
- in the method we are going to return the Promise of the built in function (fetch()), which is accepting 2 arguments:
-
API endpoint:
https://api.web3forms.com/submit. -
Object with 2 properties:
{ method: 'POST', body: formData }
- our service mail method should look like:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class MailService {
constructor() {}
sendEmail(formData: FormData): Promise<Response> {
return fetch('https://api.web3forms.com/submit', {
method: 'POST',
body: formData,
});
}
}- that's it for the mail service.
- Now let's take a look at the HTML form:
We are you using TailwindCSS for styling
<!-- Form -->
<div class="mt-8">
<form
class="flex flex-col gap-3"
#contactForm="ngForm"
(ngSubmit)="submitEmail(contactForm)"
>
<!-- Name field -->
<div>
<input
name="name"
[(ngModel)]="contactFormValues.name"
#name="ngModel"
type="text"
placeholder="Full Name"
class="w-full p-2 border border-gray-200 rounded-md"
required
minlength="2"
/>
<!-- input error message -->
<p
class="ml-1 text-red-400 text-sm"
*ngIf="name.errors && name.touched && name.dirty"
>
name is required
</p>
</div>
<!-- email field -->
<div>
<input
name="email"
[(ngModel)]="contactFormValues.email"
#email="ngModel"
type="email"
placeholder="Email"
class="w-full p-2 border border-gray-200 rounded-md"
required
pattern="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"
/>
<!-- input error message -->
<p
class="ml-1 text-red-400 text-sm"
*ngIf="email.errors && email.touched && email.dirty"
>
invalid email
</p>
</div>
<!-- body field -->
<div>
<textarea
name="body"
[(ngModel)]="contactFormValues.body"
#body="ngModel"
cols="30"
rows="10"
class="w-full p-2 border border-gray-200 rounded-md"
placeholder="Message"
required
minlength="20"
></textarea>
<!-- input error message -->
<p
class="ml-1 text-red-400 text-sm"
*ngIf="body.errors && body.touched && body.dirty"
>
at least write some words (20 characters length)
</p>
</div>
<!-- Alert -->
<div
[ngClass]="{
hidden: !showAlert
}"
>
<p [ngClass]="alertColor" class="font-semibold">
{{ alertMessage }}
</p>
</div>
<!-- submit button -->
<button
[disabled]="contactForm.invalid || onSubmit"
class="p-2 rounded-md font-bold uppercase text-white bg-light-color hover:bg-primary-color transition disabled:opacity-50 disabled:bg-light-color"
>
<ng-container *ngIf="onSubmit === false; else submittingEmail">
send
</ng-container>
<ng-template #submittingEmail>
<div class="animate-spin">
<fa-icon [icon]="iconLoad"></fa-icon>
</div>
</ng-template>
</button>
</form>-
As you can see we are assigning the values of the inputs to an object in our component class (contactFormValues) with the help of template forms, and we have a button being used to submit the form as well as we have (ng-container) and (ng-template) inside the button tag to display whether the text (send) or show a spinning animated (icon) that indicates the form is being submitted.
-
Let's take a look at the component class properties and methods:
- Class properties:
constructor(
private mailService: MailService
) {}
private color: string = '';
showAlert: boolean = false;
alertMessage: string = '';
onSubmit: boolean = false;
iconLoad = faArrowRotateForward;
contactFormValues = {
name: '',
email: '',
body: '',
};
- Class methods:
get alertColor() {
return `text-${this.color}-400`;
}
hideAlert() {
setTimeout(() => {
this.showAlert = false;
}, 5000);
}
async submitEmail(contactForm: NgForm) {
this.onSubmit = true;
// -- set formData values
let formData: FormData = new FormData();
formData.append('name', this.contactFormValues.name);
formData.append('email', this.contactFormValues.email);
formData.append('body', this.contactFormValues.body);
// -- email customization
formData.append('access_key', environment.form_access_key);
formData.append('subject', 'Email Support From Your Site');
formData.append('from_name', 'Contact Notification');
try {
// -- send email
const res = await this.mailService.sendEmail(formData);
if (!res.ok) {
throw new Error();
}
this.alertMessage = 'Email sent successfully!';
this.color = 'green';
contactForm.reset();
} catch (err) {
// handle error
this.alertMessage = 'Something went wrong, try again later!';
this.color = 'red';
}
// -- reset submit and hide alert
this.onSubmit = false;
this.showAlert = true;
this.hideAlert();
}-
showAlert: boolean = false;To display alert message (success or fail). -
alertMessage: string = '';To hold the alert message. -
onSubmit: boolean = false;To set and track submit state. -
iconLoad = faArrowRotateForward;To define and rename the icon from (fontAwesome library). -
contactFormValues
contactFormValues = { name: '', email: '', body: '', };
To hold the inputs' values with the help of the template forms of Angular.
-
hideAlert()To hide the alert message after 5 seconds. -
submitEmail(contactForm)An async function that accepts an instance of the NgForm to handle the submit form and in this method let's explain 3 parts of it:
- Create a formData instance and append values (contactFormValues) because it is the way that Web3Forms accepts the form.
formData.append('name', this.contactFormValues.name);add input value (name) from template to formData, follow the same steps to add the other inputs' values (email, body).- grab your access key from email you received earlier and add it into the environment variables, in our case we called it (form_access_key) see example below:
formData.append('access_key', environment.form_access_key);formData.append('subject', 'Email Support From Your Site');to set subject text.formData.append('from_name', 'Contact Notification');to set a name for the form.
You can read more about customizations here: Web3Forms Customization
-
try | catchblocks, in thetryblock we are calling themailService.sendEmail()method to submit the form and in case the form was successfully submitted we show a success message and reset the values tonullby the help of the instanceNgFormthat hasreset()method, in our case it iscontactForm.reset(), and in case there is an error we added a guard clause and inside its block we throw an error to force the code to jump to thecatchblock and show an error message. -
and at the end of the method we reset
onSubmitproperty tofalse,showAlerttotrueand call thehideAlert()method.
Congratulations! You are all set up and ready to go.
This article is written by CoderNadir