Post Date: October 22, 2018
Last Updated: September 29, 2026
Introduction
Signup and profile forms are common requirements in web applications. A typical application needs to collect user information through a frontend form, send that data to a backend API, store it in a database, and allow users or administrators to edit the saved information later.
The original version of this article demonstrated this workflow using Angular 2, the deprecated @angular/http module, direct DOM access, PHP, and MySQL. Modern Angular applications use Reactive Forms and HttpClient, while the backend should validate incoming data and use prepared SQL statements to protect the database.
In this updated tutorial, we will build a simple user signup and edit workflow using:
- Angular
- Angular Reactive Forms
- Angular
HttpClient - PHP
- MySQL
- REST-style API endpoints
The example collects the following information:
- Name
- Gender
- Qualification
- Hobbies
- Phone number
Prerequisites
Before starting, make sure you have:
- Node.js and npm installed
- Angular CLI installed
- A supported Angular development environment
- PHP installed
- MySQL installed
- A web server such as Apache or Nginx with PHP support
- Basic knowledge of Angular, PHP, and SQL
Note: Angular is continuously updated. The commands and APIs below follow the modern Angular approach rather than the Angular 2 APIs used in the original 2018 article.
Implementation
Part 1: Create the Angular Application
Step 1: Create a New Angular Project
Create a new Angular application:
ng new user-management
Move into the project directory:
cd user-management
Start the development server:
ng serve
Open the application in your browser:
http://localhost:4200
Step 2: Generate the Signup Component
Create a component for the user form:
ng generate component signup
This creates the component files under:
src/app/signup/
The main files include:
signup.component.ts signup.component.html signup.component.css
Part 2: Create the Signup Form
Step 3: Configure Reactive Forms
For a modern Angular application, Reactive Forms are preferable to directly reading values from HTML elements.
Depending on your Angular project structure, import ReactiveFormsModule into the appropriate application/module configuration.
For a standalone Angular application, the component can import the required functionality directly.
Example:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-signup',
standalone: true,
imports: [ReactiveFormsModule],
templateUrl: './signup.component.html'
})
export class SignupComponent {
signupForm: FormGroup;
constructor(
private fb: FormBuilder,
private http: HttpClient
) {
this.signupForm = this.fb.group({
name: ['', Validators.required],
gender: ['', Validators.required],
mail: ['', [Validators.required, Validators.email]],
qualification: ['', Validators.required],
hobbies: [''],
phone: ['', Validators.required]
});
}
submitForm(): void {
if (this.signupForm.invalid) {
this.signupForm.markAllAsTouched();
return;
}
this.http.post(
'http://localhost/api/signup.php',
this.signupForm.value
).subscribe({
next: response => {
console.log('User created successfully', response);
},
error: error => {
console.error('Error creating user', error);
}
});
}
}
Important:
HttpClientreplaces the old@angular/httpimplementation used in Angular 2 applications.
Step 4: Create the HTML Form
Update signup.component.html:
<h1>Welcome to Our Website</h1>
<h2>Please Enter Your Details</h2>
<form [formGroup]="signupForm" (ngSubmit)="submitForm()">
<div>
<label for="name">Name</label>
<input
id="name"
type="text"
formControlName="name"
>
</div>
<div>
<label for="gender">Gender</label>
<input
id="gender"
type="text"
formControlName="gender"
>
</div>
<div>
<label for="mail">Email</label>
<input
id="mail"
type="email"
formControlName="mail"
>
</div>
<div>
<label for="qualification">Qualification</label>
<input
id="qualification"
type="text"
formControlName="qualification"
>
</div>
<div>
<label for="hobbies">Hobbies</label>
<input
id="hobbies"
type="text"
formControlName="hobbies"
>
</div>
<div>
<label for="phone">Phone Number</label>
<input
id="phone"
type="tel"
formControlName="phone"
>
</div>
<button type="submit">
Submit
</button>
</form>
This approach allows Angular to manage the form state instead of using document.getElementById().
Part 3: Configure HttpClient
Step 5: Enable HttpClient
The Angular application needs HttpClient to communicate with the PHP backend.
For a standalone Angular application, configure the application with provideHttpClient().
For example:
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient()
]
};
The exact application configuration can vary depending on the Angular version and project structure.
Part 4: Create the MySQL Database
Step 6: Create the Database
Open MySQL:
mysql -u root -p
Create the database:
CREATE DATABASE user_management;
Select the database:
USE user_management;
Step 7: Create the Users Table
Create a table for storing the signup information:
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
gender VARCHAR(30) NOT NULL,
mail VARCHAR(255) NOT NULL,
qualification VARCHAR(150) NOT NULL,
hobbies VARCHAR(255),
phone VARCHAR(30),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
For a production application, additional constraints, indexes, and normalization may be appropriate depending on the application requirements.
Part 5: Create the PHP API
Step 8: Create the API Directory
Create an API directory on the PHP server:
api/
For example:
api/ ├── config.php ├── signup.php └── update-user.php
Step 9: Create the Database Connection
Create:
config.php
Add:
<?php
$servername = "localhost";
$dbname = "user_management";
$username = "app_user";
$password = "CHANGE_THIS_PASSWORD";
$conn = new mysqli(
$servername,
$username,
$password,
$dbname
);
if ($conn->connect_error) {
http_response_code(500);
die("Database connection failed.");
}
$conn->set_charset("utf8mb4");
Security Note: Do not commit database passwords to Git repositories. Production credentials should be stored securely through environment variables or a protected configuration mechanism.
Part 6: Create the Signup API
Step 10: Create signup.php
Create:
signup.php
Add:
<?php
header('Content-Type: application/json');
require_once 'config.php';
$data = json_decode(file_get_contents('php://input'), true);
$name = trim($data['name'] ?? '');
$gender = trim($data['gender'] ?? '');
$mail = trim($data['mail'] ?? '');
$qualification = trim($data['qualification'] ?? '');
$hobbies = trim($data['hobbies'] ?? '');
$phone = trim($data['phone'] ?? '');
if ($name === '' || $gender === '' || $mail === '' || $qualification === '') {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Required fields are missing.'
]);
exit;
}
if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Invalid email address.'
]);
exit;
}
$stmt = $conn->prepare(
"INSERT INTO users
(name, gender, mail, qualification, hobbies, phone)
VALUES (?, ?, ?, ?, ?, ?)"
);
$stmt->bind_param(
"ssssss",
$name,
$gender,
$mail,
$qualification,
$hobbies,
$phone
);
if ($stmt->execute()) {
echo json_encode([
'success' => true,
'message' => 'User created successfully.',
'id' => $stmt->insert_id
]);
} else {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => 'Unable to create user.'
]);
}
$stmt->close();
$conn->close();
The important difference from the original article is the use of a prepared statement rather than directly inserting user-controlled values into an SQL query.
Part 7: Edit Existing User Details
Creating the signup form is only part of the workflow. Applications commonly need an edit operation so that existing user information can be updated.
Step 11: Create the Update API
Create:
update-user.php
Example:
<?php
header('Content-Type: application/json');
require_once 'config.php';
$data = json_decode(file_get_contents('php://input'), true);
$id = (int) ($data['id'] ?? 0);
$name = trim($data['name'] ?? '');
$gender = trim($data['gender'] ?? '');
$mail = trim($data['mail'] ?? '');
$qualification = trim($data['qualification'] ?? '');
$hobbies = trim($data['hobbies'] ?? '');
$phone = trim($data['phone'] ?? '');
if ($id <= 0) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Invalid user ID.'
]);
exit;
}
if ($name === '' || $gender === '' || $mail === '' || $qualification === '') {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Required fields are missing.'
]);
exit;
}
if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'Invalid email address.'
]);
exit;
}
$stmt = $conn->prepare(
"UPDATE users
SET name = ?,
gender = ?,
mail = ?,
qualification = ?,
hobbies = ?,
phone = ?
WHERE id = ?"
);
$stmt->bind_param(
"ssssssi",
$name,
$gender,
$mail,
$qualification,
$hobbies,
$phone,
$id
);
if ($stmt->execute()) {
echo json_encode([
'success' => true,
'message' => 'User details updated successfully.'
]);
} else {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => 'Unable to update user details.'
]);
}
$stmt->close();
$conn->close();
Part 8: Update the Angular Form
The same Angular form can be reused for both creating and editing a user.
For an edit operation, populate the form with the existing user information:
this.signupForm.patchValue({
name: user.name,
gender: user.gender,
mail: user.mail,
qualification: user.qualification,
hobbies: user.hobbies,
phone: user.phone
});
When updating an existing user, include the user ID in the request:
const payload = {
id: userId,
...this.signupForm.value
};
this.http.put(
'http://localhost/api/update-user.php',
payload
).subscribe({
next: response => {
console.log('User updated successfully', response);
},
error: error => {
console.error('Update failed', error);
}
});
Part 9: Handle CORS
If Angular and PHP are running on different origins during development, the browser may block the API request because of Cross-Origin Resource Sharing (CORS).
For example:
Angular: http://localhost:4200 PHP API: http://localhost/api/
The PHP API can return an appropriate CORS header:
header('Access-Control-Allow-Origin: http://localhost:4200');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
For production, do not use:
Access-Control-Allow-Origin: *
unless it is intentionally required and appropriate for the application’s security model.
Restrict API access to the required trusted origins.
Part 10: Test the Application
Start the Angular application:
ng serve
Make sure the PHP API and MySQL service are also running.
Open:
http://localhost:4200
Enter the user information and submit the form.
Then verify the database:
SELECT * FROM users;
You should see the newly created record.
Troubleshooting
Angular Cannot Reach the PHP API
Check:
- PHP web server status
- API URL
- Browser developer console
- Network tab
- CORS configuration
- PHP error logs
- Firewall rules
Test the PHP endpoint directly:
curl -i http://localhost/api/signup.php
Database Connection Fails
Check:
- MySQL service status
- Database name
- Database username
- Database password
- MySQL permissions
- PHP MySQL extension
For example:
php -m | grep mysqli
CORS Error in the Browser
If the browser reports a CORS error, verify that the PHP API returns the required CORS headers and that the Angular application’s origin is allowed.
Do not solve CORS issues by blindly allowing every origin in production.
Form Data Is Not Being Submitted
Check the browser’s developer console and Network tab.
Verify that the Angular form contains:
[formGroup]="signupForm"
and that the submit button is inside the form:
<button type="submit"> Submit </button>
Also confirm that the form is valid before sending the request.
Security Recommendations
A signup or profile form handles user-provided information and should not rely only on frontend validation.
Validate Data on the Server
Angular validation improves the user experience, but all important validation must also happen on the backend.
Use Prepared Statements
Always use prepared SQL statements for user-controlled values.
Avoid:
$sql = "INSERT INTO users VALUES ('$name')";
Use prepared statements instead:
$stmt = $conn->prepare(
"INSERT INTO users (name) VALUES (?)"
);
Protect Database Credentials
Do not commit credentials to Git:
username = "app_user" password = "production-password"
Use environment variables or a protected server-side configuration.
Use HTTPS
Production applications should use HTTPS so that form submissions and API requests are encrypted in transit.
Implement Authentication and Authorization
The example demonstrates the form and API workflow only. A real profile-editing system should authenticate the user and verify that the authenticated user has permission to modify the requested record.
Do not allow an unauthenticated API request to modify arbitrary user IDs.
Modern Angular vs. the Original Angular 2 Implementation
The original article used several APIs and patterns that are no longer appropriate for modern Angular applications.
| Original approach | Modern approach |
|---|---|
| Angular 2 | Current supported Angular releases |
@angular/http | @angular/common/http |
Http | HttpClient |
Direct document.getElementById() | Reactive Forms |
| Manually building form parameters | Form model / JSON payload |
| Raw SQL values | Prepared statements |
| Client-side-only validation | Client + server validation |
| Hard-coded database credentials | Protected configuration |
| Simple PHP script | Validated API endpoint |
Conclusion
The original Angular 2 example demonstrated the basic concept of collecting signup information and sending it to a PHP/MySQL backend.
For modern applications, the same workflow should be implemented using Angular Reactive Forms, HttpClient, server-side validation, PHP APIs, and MySQL prepared statements.
The architecture can then be extended with authentication, authorization, user listing, profile editing, pagination, API error handling, audit logging, and stronger security controls.
Frequently Asked Questions
1. Can I still use Angular 2 for this project?
Angular 2 is obsolete and should not be selected for a new application. Existing legacy applications should be evaluated for migration to a currently supported Angular version.
2. Why should I use Reactive Forms?
Reactive Forms provide structured form state and validation and are easier to maintain as an application becomes more complex.
3. Why was document.getElementById() removed from the example?
Angular applications should generally manage UI state through Angular’s component and form APIs rather than directly manipulating DOM elements.
4. Why should I use prepared statements?
Prepared statements separate SQL instructions from user-provided values and significantly reduce the risk of SQL injection.
5. Can Angular connect directly to MySQL?
No. A browser-based Angular application should not connect directly to a MySQL database. A backend API should handle database communication.
6. Can the same form be used for signup and editing?
Yes. The form can be populated with an existing user’s data using patchValue() and submitted to an update endpoint.
Related Articles
- How to create a Signup form and edit the details using Angular2
- How to Fix an Empty Angular Page with Laravel and Nginx
Pheonix Solutions Can Help
Need help modernizing a legacy Angular application or building a secure web application from the ground up? Pheonix Solutions can help with Angular development, API integration, PHP and MySQL development, application modernization, security, testing, cloud deployment, automation, and ongoing application support.
Pingback: Edit the profile details using Angular2 - PHEONIX SOLUTIONS