Angular JS vs. React JS

Angular and React are two of the top frontend frameworks for web applications. Though their scopes are slightly different (one a development platform, the other a library), they’re seen as major competitors. It’s safe to assume that you can use either framework to develop an application.

The major question then becomes: why would you choose one over the other? This article aims to answer it by developing a simple signup form. The form will rely on each framework of validation capabilities of.

Prerequisites

To continue, you should be able to install React and have a general understanding of how a React application works. You should also know how to install and use Angular.

The File Structure of Each Application

The React form has the following file structure:

The Angular form has the following file structure:

The image above only displays the edited section of the Angular application.

From the file structures above you can see that both frameworks rely heavily on the use of components.

Creating the Logic for Each Form Application

Each application will have the same purpose: the form only submits if every input field contains valid data. The username field is valid if it contains at least one character. The two password fields are valid if their values ​​are identical.

Angular provides two form creation methods: template-driven and reactive. The reactive approach allows the developer to create custom validation criteria. The template-driven approach comes with properties that simplify form validation.

MAKEUSEOF VIDEO OF THE DAY

React is only capable of developing a form with custom validation. However, React is the more popular framework and it has a larger community, so many form-handling libraries are available for React. Given that the goal here is to avoid the use of external libraries, the React application will rely on custom validation.

Developing the Template for Each Application

Both applications rely on templates to create the final HTML output.

Angular HTML Template

The form-signup.component.html file contains the following code:

<div class="form-content">
<form class="form" #myForm="ngForm">
<h1>Complete the form to join our community!</h1>

<div class="form-inputs">
<label for="username" class="form-label">Username:</label>

<input
id="username"
type="text"
class="form-input"
placeholder="Enter username"
name="username"
ngModel
required
#username="ngModel"
/>

<p *ngIf="username.invalid && username.touched">Username required</p>
</div>

<div class="form-inputs">
<label for="password" class="form-label">Password:</label>

<input
id="password"
type="password"
name="password"
class="form-input"
placeholder="Enter password"
ngModel
required
#password="ngModel"
[(ngModel)]="model.password"
/>

<p *ngIf="password.invalid && password.touched">password required</p>
</div>

<div class="form-inputs">
<label for="passwordvalidate" class="form-label">Password:</label>

<input
id="confirmpassword"
type="password"
name="confirmpassword"
class="form-input"
placeholder="Confirm password"
ngModel
required
#password2="ngModel"
ngValidateEqual="password"
[(ngModel)]="model.confirmpassword"
/>

<div *ngIf="(password2.dirty || password2.touched) && password2.invalid">
<p *ngIf="password2.hasError('notEqual') && password.valid">
Passwords do not match
</p>
</div>
</div>

<button
class="form-input-btn"
type="submit"
[disabled]="myForm.invalid"
routerLink="/success"
>
Sign Up
</button>
</form>
</div>


React HTML Template

The Signup.js file contains the following code:

import React from "react";
import useForm from "../useForm";
import validate from "../validateData";
import "./Signup.css"

const Signup = ({submitForm}) => {
const {handleChange, values, handleSubmit, errors} = useForm( submitForm, validate);

return (
<div className="form-content">
<form className="form" onSubmit={handleSubmit}>
<h1>Complete the form to join our community!</h1>

<div className="form-inputs">
<label htmlFor="username" className="form-label">Username:</label>

<input
id="username"
type="text"
name="username"
className="form-input"
placeholder="Enter username"
value={values.username}
onChange={handleChange}
/>

{errors.username && <p>{errors.username}</p>}
</div>

<div className="form-inputs">
<label htmlFor="password" className="form-label"> Password: </label>

<input
id="password"
type="password"
name="password"
className="form-input"
placeholder="Enter password"
value={values.password}
onChange={handleChange}
/>

{errors.password && <p>{errors.password}</p>}
</div>

<div className="form-inputs">
<label htmlFor="passwordvalidate" className="form-label"> Password: </label>

<input
id="passwordvalidate"
type="password"
name="passwordvalidate"
className="form-input"
placeholder="Confirm password"
value={values.passwordvalidate}
onChange={handleChange}
/>

{errors.passwordvalidate && <p>{errors.passwordvalidate}</p>}
</div>

<button className="form-input-btn" type="submit">Sign Up</button>
</form>
</div>
)
}
export default Signup;


You’ll notice that both applications use basic HTML code, except for some minor differences. For example, the Angular application uses the standard “class” attribute to identify CSS classes. React uses its own custom “className” property. React transforms this into the standard “class” attribute in the final output. The UI plays an important role in the success of any application. Since both applications use the same HTML structure and class names, both applications can use the same stylesheet.

All the non-standard properties in the templates above relate to validation.

Creating the Form Validation for the Angular Application

To access the validation properties that are a part of Angular’s template-driven approach, you’ll need to import the FormsModule in the app.module.ts file.


The app.module.ts File

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { ValidateEqualModule } from 'ng-validate-equal'

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormSignupComponent } from './form-signup/form-signup.component';
import { FormSuccessComponent } from './form-success/form-success.component';

@NgModule({
declarations: [
AppComponent,
FormSignupComponent,
FormSuccessComponent
],
imports: [
BrowserModule,
FormsModule,
ValidateEqualModule,
AppRoutingModule
],
providers: [],
bootstrap: [ AppComponent ]
})

export class AppModule { }


By importing the FormsModule in the file above, you now have access to a range of different validation properties. You’ll need to add the ngModel property to the input fields of the Angular HTML template. If you look back at the Angular template above, you’ll see that each of the input elements has this property.

The FormsModule and ngModel give the developer access to validation properties such as valid and invalid. The paragraph section of the Angular HTML template uses the #username=”ngModel” property. It produces a warning if the data in the input field is invalid and the user has changed it.

In the app.module.ts file, you’ll also see the ValidateEqualModule, which compares the two passwords. To do this, you’ll need to create a model object in the form-signup.component.ts file.

The form-signup.component.ts File

import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-form-signup',
templateUrl: './form-signup.component.html',
styleUrls: ['./form-signup.component.css']
})

export class FormSignupComponent implements OnInit {
constructor() { }
ngOnInit(): void {}
model = {
password: null,
confirmpassword: null
};
}

The second password in the Angular HTML template uses the model object in the file above, to compare its value to the first password.

The disabled property on the submit button ensures that it remains inactive until every input field contains valid data. Submitting the form brings the user to a success page with the aid of Angular’s router.

The app.routing.module.ts File

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FormSignupComponent } from './form-signup/form-signup.component';
import { FormSuccessComponent } from './form-success/form-success.component';

const routes: Routes = [{
path: '',
component: FormSignupComponent
},{
path: 'success',
component: FormSuccessComponent
}];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})

export class AppRoutingModule { }

The routing module above contains two paths; the main path for the form and a success path for the success component.

The app.component.html File

<router-outlet></router-outlet>

The router outlet in the app component file above allows a user to easily navigate between the form-signup and form-success components using URLs.

Creating the Form Validation for the React Application

export default function validateData(values) {
let errors = {}

if (!values.username.trim()) {
errors.username = "Username required";
}

if (!values.password) {
errors.password = "Password required";
}

if (!values.passwordvalidate) {
errors.passwordvalidate = "Password required";
} else if (values.passwordvalidate !== values.password) {
errors.passwordvalidate = "Passwords do not match";
}

return errors;
}

The validateData.js file contains the code above. It monitors each input field in the form to ensure that each field contains valid data.

The useForm.js File

import {useState, useEffect} from 'react';

const useForm = (callback, validate) => {
const [values, setValues] = useState({
username: '',
password: '',
passwordvalidate: ''
});

const [errors, setErrors] = useState ({});

const [isSubmitting, setIsSubmitting] = useState (false)

const handleChange = e => {
const {name, value} = e.target;

setValues({
...values,
[name]: value
});
}

const handleSubmit = e => {
e.preventDefault();
setErrors(validate(values));
setIsSubmitting(true);
}
useEffect(() => {
if (Object.keys(errors).length === 0 && isSubmitting) {
callback();
}
}, [errors, callback, isSubmitting]);

return { handleChange, values, handleSubmit, errors };
}

export default useForm;


The custom useForm hook above determines if the user successfully submits the form. This event only occurs if all the data within the form is valid.

The Form.js File

import React from "react";
import Signup from "./Signup";
import Success from "./Success"
import { useState } from "react";

const Form = () => {
const [isSubmitted, setIsSubmitted] = useState(false);

function submitForm() {
setIsSubmitted(true);
}

return (
<div>
{!isSubmitted ? (<Signup submitForm={submitForm} />) : (<Success />)}
</div>
)
}

export default Form;

The Form component above switches the view between the Signup component and the Success component if the form submits.

The App.js File

import Form from "./components/Form";

function App() {
return (
<div className="App">
<Form/>
</div>
);
}

export default App;

The Angular Application UI

The UI displays a form with one input for the username and two password inputs.

When the form contains invalid data, the pages displays error messages:

When the form contains valid data, the user can submit it successfully:

The React Application UI

When the form contains invalid data:

When the form contains valid data:

Similarities and differences between React and Angular

The Angular and React frameworks are remarkably similar and capable of producing identical results. However, the tools that you might use to achieve these results will differ. Angular is a development platform that provides access to tools such as a router and a form library. React requires a little more creativity from the developer to achieve the same results.


HTML Code on a Computer Screen

React vs. Angular: Why Is React So Much More Popular?

Read Next


About The Author

Leave a Comment

Your email address will not be published.