Published on

How to upload images to Cloudinary in Angular.js

This is what we’ll build today!

Figure 1: This is what we’ll build today!

Do you know what company provides Image and Video APIs, Dynamic Asset Management features, Media Optimization tools and numerous SDK, Platform and Add-on Integrations on top of having an excellent customer support network? Cloudinary, of course!

In this tutorial we will go over how to implement an image upload form, using Cloudinary as the image hosting provider, for an Angular application. It is definitely going to be very informative so let’s jump right in!

Prerequisites

To get started with using Cloudinary you’ll need to have an existing Angular project in which to implement the features we’ll cover in this tutorial. If you don’t, you can learn how to create a new Angular project at the Angular official website by clicking here

Also, you’ll need to register a Cloudinary account in order to use their image upload services, which you can easily do by visiting their Registration page here.

Note: If you ever need the source code for this application, it can be found in my GitHub repository here.

Now let’s get coding!

Setup

First, we’ll need to install some npm packages that our application relies on. So let’s run this command in order to install and save these packages into our package.json file:

npm install --save @cloudinary/angular-5.x @fortawesome/angular-fontawesome @fortawesome/fontawesome-svg-core @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/free-solid-svg-icons angular-progress-bar cloudinary-core ng2-file-upload
The @cloudinary/angular-5.x, cloudinary-core and ng2-file-upload packages will allow us to use Cloudinary’s image uploading functionality in our application and the @fortawesome/angular-fontawesome package and it’s related packages will provide us the ability to use Font Awesome icons in our application.

Next, we have to create one component called ImageUpload and one service called CloudinaryService. Here are the commands to do so:

// creating ImageUpload component
ng generate component image-upload

// creating a 'services' folder and
// a CloudinaryService class inside it
mkdir services
cd services
ng generate service cloudinary

Let’s not forgot an important step: adding Cloudinary functionality into our application through the app.module.ts file(the lines you need to add are highlighted in red):

export const cloudinary = {
  Cloudinary: CloudinaryCore
};
export const config: CloudinaryConfiguration = cloudinaryConfiguration;

@NgModule({
  declarations: [
    AppComponent,
    ImageUploadComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    CloudinaryModule.forRoot(cloudinary, config),
    HttpClientModule,
    FileUploadModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
And finally we need to create a config.ts file that will contain the Cloudinary credentials that’ll be used to connect with the Cloudinary API. Make sure to create the config.ts file in the src/app folder and include the following content in it:

export default {
    cloud_name: '<your_name_here>',
    upload_preset: '<your_preset_name_here>'
};

Note: Remember to replace values highlighted in red with your actual Cloudinary Cloud name and upload preset. To find out your Cloudinary credentials please log into Cloudinary here and visit the Settings page

Now that our application is configured to use Cloudinary’s services, we have to complete the additional step of setting the upload_preset from signed to unsigned. To do this, log into Cloudinary here and visit the Settings page. Then click on the Upload tab, scroll down to the Upload Presets sections and click on the Edit button. In the following page, change the Signing Mode value from Signed to Unsigned.

Make sure Signing Mode is set to Unsigned

Figure 2: Make sure Signing Mode is set to Unsigned

Okay, let’s get back to our Angular application and code out the CloudinaryService class!

In the cloudinary.service.ts file, start by adding the following Typescript code:

@Injectable({
  providedIn: 'root'
})
export class CloudinaryService {
  uploaderOptions: FileUploaderOptions = {
    url: `https://api.cloudinary.com/v1_1/${this.cloudinary.config().cloud_name}/upload`,
    autoUpload: false,
    isHTML5: true,
    removeAfterUpload: true,
    // XHR request headers
    headers: [
      {
        name: 'X-Requested-With',
        value: 'XMLHttpRequest'
      }
    ],
  };
  uploader: FileUploader = new FileUploader(this.uploaderOptions)
  @Input()
  responses: Array<any>;
  title: string;

  hasBaseDropZoneOver: boolean = false;
  constructor(
    private cloudinary: Cloudinary,
    private zone: NgZone,
    private http: HttpClient
    ) {
    this.responses = [];
    this.title = '';
  }

  ngOnInit(){
  }

Now for an explanation of the important parts of what we we just added:

  • The uploaderOptions and uploader variables setup the Cloudinary uploader service by defining the API endpoint, HTTP request headers and the option to disable auto uploading of the selected image file
  • The responses array is used to store the file response objects that are sent from Cloudinary to our application. The file response objects can be used to extract the uploaded image file’s URL path so that displaying the uploaded image becomes very easy
  • Continuing with the cloudinary.service.ts file, we have to add the all important uploadToCloudinary() method like so:
@Injectable({
  providedIn: 'root'
})
export class CloudinaryService {
  uploaderOptions: FileUploaderOptions = {
    url: `https://api.cloudinary.com/v1_1/${this.cloudinary.config().cloud_name}/upload`,
    autoUpload: false,
    isHTML5: true,
    removeAfterUpload: true,
    // XHR request headers
    headers: [
      {
        name: 'X-Requested-With',
        value: 'XMLHttpRequest'
      }
    ],
  };
  uploader: FileUploader = new FileUploader(this.uploaderOptions)
  @Input()
  responses: Array<any>;
  title: string;

  hasBaseDropZoneOver: boolean = false;
  constructor(
    private cloudinary: Cloudinary,
    private zone: NgZone,
    private http: HttpClient
    ) {
    this.responses = [];
    this.title = '';
  }

  ngOnInit(){
  }
}

The uploadToCloudinary() method defines the onBuildItemForm, onProgressItem and onCompleteItem extension points that build the file upload form along with defining the behavior for when the file upload is in progress and when it is completed. As you can see, once the file upload event is completed, a response containing the file property information, the upload status and the file data is issued to the caller.

And that’s it for the CloudinaryService class. On to the ImageUploadComponent!

In the image-upload.component.ts file, let’s add the following content:

export class ImageUploadComponent implements OnInit {
  blob = new Array<Blob>();
  fileupload: File = new File(this.blob, '');
  imageUrl: string | ArrayBuffer | null = null;

  constructor(

    public cloudinaryService: CloudinaryService,
    private cdr: ChangeDetectorRef
    ) { }

  ngOnInit(): void {
    this.cloudinaryService.responses = [];
    this.cloudinaryService.uploadToCloudinary();
  }

   imageSelectForUpload(event: { target: HTMLInputElement }){
    this.fileupload = event.target.files![0];
    var reader = new FileReader();
    reader.readAsDataURL(this.fileupload);
    reader.onload = (_event) => {
      this.imageUrl = reader.result;
      console.log(this.imageUrl?.toString());
      this.cdr.detectChanges();
    }
  }
}

And now for a quick overview of what we just added:

  • The blob, fileupload and imageUrl variables are used preview the selected image file in the web page before it is uploaded to Cloudinary
  • The cdr: ChangeDetectorRef variable is used to notify Angular to refresh the DOM when the imageUrl variable is assigned the selected image file’s binary data(which is done in the imageSelectForUpload() method)
  • In the ngOnInit() lifecycle hook, we call the CloudinaryService‘s uploadToCloudinary() method to instantiate the uploader variable so that file uploading becomes possible
  • The imageSelectForUpload() method is responsible for displaying a preview of the selected image to the web page prior to the image file being uploaded to Cloudinary

And now for the Image Upload component’s template file code(contained in the image-upload.component.html file):

// image-upload.component.html file
<div class="body-container-wrapper">
  <div class="body-container">
    <div class="page-center">
      <i class="fa fa-cloud" aria-hidden="true"></i>
      <h1>Upload Your <strong>Files</strong> To Cloudinary</h1>
        <div id="drop">
                <input type="file" id="fileupload" class="" name="fileupload" #fileInput ng2FileSelect [uploader]="cloudinaryService.uploader" (change)="imageSelectForUpload($event)"
                />
                <img [src]="imageUrl" *ngIf="imageUrl" class="selected-image"/>
                <button type="button" class="btn btn-success btn-s upload"
                (click)="cloudinaryService.uploader.uploadAll()"
                [disabled]="!cloudinaryService.uploader.getNotUploadedItems().length" >
                    <span>Upload Image!</span>
                </button>
          </div>
      <div class="file-upload-bar">
        <div class="bar-wrapper">
          <div class="overall"><span>Overall Progress</span>
            <div class="file" *ngFor="let response of cloudinaryService.responses; let i = index">
                <h3>{{response.file.name}}</h3>
            <button class="delete-image" *ngIf="!!response.data.delete_token" (click)="cloudinaryService.deleteImage(response.data, i)">Delete image</button>
                <div class="status">
                    Uploading... {{response.progress}}%
                    <div *ngIf="!response.status">In progress</div>
                    <div class="status-code" *ngIf="response.status">Upload completed with status code {{response.status}}</div>
                </div>
                <div class="progress-bar-overall progress-bar">
                    <div class="progress" role="progressbar" [style.width.%]="response.progress"></div>
                </div>
            </div>
          </div>
        </div>
      </div>
      <div class="file-upload-bar-closed"></div>
    </div>
  </div>
</div>

The above template file will render a basic file upload form to the web page.

Finally let’s pretty things up with some CSS styles in the image-upload.component.css file. For the sake of brevity, just visit this GitHub link to copy and paste all the CSS styles to your image-upload.component.css file.

Lastly, we just need to add Image Upload component to the App component’s template page so that it can be rendered on to the main page of our Angular application. So, in your app.component.html add the following line:

<app-image-upload></app-image-upload>

and that concludes the setup required for our application!

Run The Application

Now it’s time to test out our application by running the following commands:

// installs all dependencies for the application
npm install
// starts the application
npm start

Now if you visit http://localhost:4200 on your browser you should see the following web page:

Our finished Application!

Figure 3: Our finished Application!

Click the ‘Choose File’ button to select an image file to upload to Cloudinary and click ‘Upload Image!’ when you want to do so.

That’s it for the development of this application so give yourself a pat on the back if you managed to get this working the first time around! If not, keep trying and you will get there 🙂

Conclusion

Thanks for following along in this tutorial and if you have any questions or concerns please feel free to post a comment in this article and I will get back to you if I find the time.

I hope you found this article helpful. Thanks so much for reading my article! Feel free to follow me on Twitter and GitHub, connect with me on LinkedIn and subscribe to my YouTube channel.