Question
How can I create a file-upload feature in an Angular 5 application? I am new to Angular and need a beginner-friendly approach or documentation. I tried using the ng4-files package, but it does not work with Angular 5.
Short Answer
You will learn how browser file inputs work in Angular, how to read the selected File, and how to send it to a server with FormData and Angular's HttpClient. You will also see basic validation, upload progress handling, and a reusable component structure.
Concept
A file upload has two separate jobs:
- Choose a file in the browser using an HTML
<input type="file">element. - Send that file to a server using an HTTP request.
Angular does not need a special package for the basic version. The browser already provides a File object when a user selects a file. Your Angular component stores that object, places it in a FormData instance, and sends the form data to an API endpoint.
FormData is important because files are binary data. It creates a request using multipart/form-data, the standard request format that servers use for form submissions containing files.
In Angular 5, use HttpClient from @angular/common/http. It replaces the older Http service and supports typed responses and upload-progress events.
A successful upload still requires a backend endpoint such as POST /api/uploads. Angular can select and transmit the file, but the server must validate it, store it, and return a response.
Mental Model
Think of the file input as a customer choosing a package at a shipping desk.
- The
<input type="file">lets the customer choose the package. - The browser gives Angular a
Fileobject: the package plus details such as its name, size, and type. FormDatais the shipping box and label.HttpClientis the delivery service that sends the box to the server.- The backend is the warehouse that receives and stores the package.
Selecting a file does not upload it automatically. Uploading happens only when your code sends the HTTP request.
Syntax and Examples
The core flow is:
selectedFile: File | null = null;
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;
this.selectedFile = input.files?.[0] ?? null;
}
upload(): void {
if (!this.selectedFile) {
return;
}
const formData = new FormData();
formData.append('file', this.selectedFile, this.selectedFile.name);
this.http.post('/api/uploads', formData).subscribe();
}
Template:
< = ()=>
Upload
Step by Step Execution
Consider this example:
onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;
this.selectedFile = input.files?.[0] ?? null;
}
upload(): void {
if (!this.selectedFile) {
this.message = 'Choose a file first.';
return;
}
const data = new FormData();
data.append('file', this.selectedFile, this.selectedFile.name);
this.http.post('/api/uploads', data).subscribe({
next: () => this.message = 'Upload complete.',
: . =
});
}
Real World Use Cases
File uploads appear in many applications:
- Profile settings: upload an avatar or company logo.
- Support portals: attach screenshots, logs, or documents to a ticket.
- Content management systems: upload images, PDFs, and downloadable resources.
- Business workflows: submit invoices, receipts, contracts, or spreadsheets.
- Data import tools: upload CSV files for processing.
- Messaging applications: share images and attachments.
In each case, validate both in the browser for user feedback and on the server for security. Client-side checks can be bypassed, so the server is the final authority.
Real Codebase Usage
In production Angular applications, file upload code commonly follows these patterns:
- Keep HTTP calls in a service. Components manage the user interface; an
UploadServicesends requests. - Use guard clauses. Return early when no file is selected or validation fails.
- Validate before uploading. Check size and allowed file types to give fast feedback.
- Show upload state. Disable repeated clicks while uploading and display success or failure messages.
- Track progress for larger files. Send requests with
observe: 'events'andreportProgress: true. - Let the server generate final file names. Do not trust a client-provided filename as a safe storage path.
- Handle errors explicitly. Network failure, unauthorized access, oversized files, and unsupported types all need useful messages.
A service-based upload method can look like this:
upload(file: File) {
const formData = new FormData();
formData.append('file', file, file.name);
return this.http.post('/api/uploads', formData);
}
The component subscribes to that returned observable and updates its view state.
Common Mistakes
Setting the Content-Type header manually
This is a frequent mistake:
// Incorrect for FormData
const headers = new HttpHeaders({
'Content-Type': 'multipart/form-data'
});
this.http.post('/api/uploads', formData, { headers });
Do not manually set Content-Type when sending FormData. The browser adds multipart/form-data plus a required boundary value. Set no content-type header unless your API has another specific requirement.
Sending the input value instead of the file
// Incorrect: this is usually a browser-protected path-like string, not file data.
const value = (event.target as HTMLInputElement).value;
Use input.files?.[0], which is the actual File object.
Forgetting to import HttpClientModule
Comparisons
| Approach | Best for | Notes |
|---|---|---|
Native file input + FormData | Most standard uploads | No external upload library required. |
Angular HttpClient | Angular 5 applications | Supports observables, errors, and progress events. |
Older Angular Http service | Legacy code only | Avoid for new Angular 5 code; HttpClient is preferred. |
| Uploading on file selection | Quick, immediate uploads | Start the request inside the change handler. |
| Uploading after a button click | Forms and confirmation flows | Lets the user review or replace the file first. |
| Single-file input | Avatar or one document | Read . |
Cheat Sheet
// Read one selected file
const input = event.target as HTMLInputElement;
const file = input.files?.[0] ?? null;
// Build multipart form data
const data = new FormData();
data.append('file', file, file.name);
// Send it
this.http.post('/api/uploads', data).subscribe();
- Use
<input type="file">to open the browser file picker. - Read selected files from
input.files, notinput.value. - Use
FormDatafor file requests. - The
append()field name must match what the server expects. - Import
HttpClientModuleonce in the Angular module. - Do not manually set
Content-TypeforFormData. - Use as a helpful UI hint, not as security.
FAQ
Does Angular 5 have a built-in file upload component?
Angular uses the browser's standard <input type="file">. You build the upload behavior by sending the chosen File with HttpClient and FormData.
Do I need an external Angular file upload library?
Not for standard uploads. A library can help with drag-and-drop, queues, retries, or advanced UI, but native browser APIs are enough for basic uploads.
Why is my backend receiving no file?
Check that you append the file to FormData, that the field name matches the backend expectation, and that you do not manually override the multipart Content-Type header.
Can I upload multiple files in Angular?
Yes. Add multiple to the input, convert input.files to an array, and append each file to FormData.
How do I restrict uploads to images?
Use accept="image/*" on the input and validate the selected file in TypeScript. Also enforce image validation on the server.
Can I show upload progress with Angular HttpClient?
Yes. Send the request with reportProgress: true and observe: 'events', then calculate a percentage from events.
Mini Project
Description
Build a small profile-image uploader. The user selects an image, sees its name, and uploads it to an API endpoint. The component validates the file before sending it and reports the result.
Goal
Create an Angular 5 component that uploads one PNG or JPEG image smaller than 2 MB.
Requirements
Use a native file input that accepts images only.
Store the selected file and display its name.
Reject files that are not PNG or JPEG images.
Reject files larger than 2 MB.
Send valid files to POST /api/profile-image with FormData.
Show success or error feedback.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Accessing Input Value from EventTarget in TypeScript
Learn why EventTarget has no value property in TypeScript and safely read values from HTML input events in Angular applications.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.