Angular 12 Multiple Image Uploader with Preview Example – PHP Server to Save file

Upload multiple images and preview in Angular 2+ applications; In this Angular tutorial, we will discuss how to upload multiple images with preview and how to save them on the server using PHP backend.

This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11 & Angular 12

To upload images, we will use the Angular reactive form approach. Using the form, a user can select more than one image. The images will be displayed to the user a preview before upload. After submitting the form, images will be saved into the server using the PHP backend.

How to Upload Multiple Images with Preview in Angular application?

We’ll follow these quick steps to implement the multiple-image uploaded with preview using Angular’s reactive form.

  1. Create Angular Application
  2. Import FormsModule in App Module
  3. Update View of Template Component
  4. Update Component Class
  5. Create PHP Server File
  6. Run Angular Application and Server File

 

Create Angular Application

Before creating the Angular application, make sure you have Angular CLI installed on your system.

$ npm install -g @angular/cli

After that, you are ready to create a new Angular project. Execute below CLI command to create a new angular application.

$ ng new angular-multiple-image-upload-app

Move into the project directory

$ cd angular-multiple-image-upload-app

Import FormsModule in App Module

To use the reactive form in our Angular application, we need to import the FormsModule and ReactiveFormsModule into our App Module.

Also, to trigger HTTP calls, we need HttpClientModule to provide different HTTP methods.

Open the app.module.ts file and update it with the following code.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

 

Update View of Template Component

To select image files, add a reactive form into the App Component template HTML. This form will have input form control of file type. The input field to take name value and also IMG tag to preview our selected images with a *ngFor directive to iterate over selected files.

Open the app.component.html file and update it with this template.

<div class="container">

  <h1>Multiple Image Uploader with Preview - FreakyJolly.com</h1>

  <form [formGroup]="myForm" (ngSubmit)="submit()">

    <div class="form-group">
      <label for="name">Name</label>
      <input formControlName="name" id="name" type="text" class="form-control">
      <div *ngIf="formValue.name.touched && formValue.name.invalid" class="alert alert-danger">
        <div *ngIf="formValue.name.errors && formValue.name.errors.required">Name is required.</div>
      </div>
    </div>

    <div class="form-group">
      <label for="file">File</label>
      <input formControlName="file" id="file" type="file" class="form-control-file" multiple=""
        (change)="onFileChange($event)">
      <div *ngIf="formValue.file.touched && formValue.file.invalid" class="alert alert-danger">
        <div *ngIf="formValue.file.errors && formValue.file.errors.required">File is required.</div>
      </div>
    </div>

    <div class="preview-wrapper">
      <div class="img-preview" *ngFor='let url of images'>
        <img [src]="url" width="200px">
        <button type="button" class="btn btn-danger btn-sm" (click)="removeImage(url)">Remove</button>
      </div>
    </div>

    <button class="btn btn-primary" type="submit">Submit</button>
  </form>

</div>

The image preview wrapper is listing all the selected images. Each having a Remove button to remove the selected image before upload.

There is error handling as well to show messages for required fields before submitting the form.

Update Component Class

Now, update the component class file with submit, onFileChange, remove and patchValue methods.  The formValue getter method will be used to show errors if required fields are not filled.

We are fetching the Base64 URL after the files are selected inside the onFileChange methods. Then pushing the Base64 string into the images array.

Open the app.component.html file and update it with the following code.

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormGroup, FormControl, Validators} from '@angular/forms';
   
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
   images : string[] = [];
   myForm = new FormGroup({
    name: new FormControl('', [Validators.required]),
    file: new FormControl('', [Validators.required]),
    fileSource: new FormControl('', [Validators.required])
  });
    
  constructor(private http: HttpClient) { }
    
  get formValue(){
    return this.myForm.controls;
  }
    
  onFileChange(event:any) {
    if (event.target.files && event.target.files[0]) {
        var filesAmount = event.target.files.length;
        for (let i = 0; i < filesAmount; i++) {
                var reader = new FileReader();
                reader.onload = (event:any) => {
                  // Push Base64 string
                  this.images.push(event.target.result); 
                  this.patchValues();
                }
                reader.readAsDataURL(event.target.files[i]);
        }
    }
  }

  // Patch form Values
  patchValues(){
    this.myForm.patchValue({
       fileSource: this.images
    });
  }

  // Remove Image
  removeImage(url:any){
    console.log(this.images,url);
    this.images = this.images.filter(img => (img != url));
    this.patchValues();
  }
     
  // Submit Form Data
  submit(){
    this.http.post('http://localhost:8005/upload.php', this.myForm.value)
      .subscribe(res => {
        console.log(res);
        alert('Uploaded Successfully.');
      })
  }
}

On submit. we are passing the form data to the server using POST HTTP call. We will create the PHP server in next step.

 

Setup PHP Server File

Now, head towards the application root and create the server/files folder with a PHP file named upload.php. Update the file with the following content in it.

<?php
   
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
    
$folderPath = "files/";
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
foreach ($request->fileSource as $key => $value) {
    $image_parts = explode(";base64,", $value);
    $image_type_aux = explode("image/", $image_parts[0]);
    $image_type = $image_type_aux[1];
    $image_base64 = base64_decode($image_parts[1]);
    $file = $folderPath . uniqid() . '.'.$image_type;
    file_put_contents($file, $image_base64);
}

The final folder structure will look like this.

 

Run Angular Application and Server File

Now, we will serve the Angular application and PHP server to manage our uploaded files.

Serve Angular Application

Head towards the application root folder and execute the following command in the CLI terminal window:

$ ng serve --open

This will open the Angular application on 4200 port at the following URL

http://localhost:4200/

 

Start PHP Server

To start PHP server, move inside the directory where we put the upload.php file. In our case at this location ~src\app\server

Now execute the following command to run the PHP server, that will save your uploaded files in the src\app\server\files folder

php -S localhost:8005

 

Conclusion

We are completed with multiple image uploads using the PHP server in the Angular application. The image preview section is also having the remove button to remove any selected image before uploading. We achieved this functionality using the Reactive Angular form, which converts the selected image into Base64 string format and mange an images array to push to the server. The uploaded images are saved to the file system with randomly generated names.

Hope this tutorial was helpful, d share your feedback and suggestions, thanks…

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *