Before Start
Before starting this tutorial is recommended that you create a new folder named photo-upload
running next command:
mkdir photo-upload
then go inside it with next command:
cd photo-upload
Nest API
In this section we are going to learn how to create a server-api that uses NestJs framework. You could find the full documentation of NestJs file uploading here.
Create Project
The first step will be to create a new project running next command:
nest new photo-upload-api
then change the directory of your console running next command:
cd photo-upload-api
Add Photos Controller
Now we need to create a new controller to handle the uploaded photos. To do that we need to run next command:
nest g co controllers/photos
After that modify photos.controller.ts
file with next code:
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
@Controller('photos')
export class PhotosController {
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
upload(@UploadedFile() file) {
console.log('file: ', file);
return {message: 'Upload Success'};
}
}
Running the app
Once you have done all that its time to start the server API by running next commands:
development
npm run start
watch mode
npm run start:dev
production mode
npm run start:prod
Ionic Client
In this section, we will create an Ionic Angular app that works on the web, iOS, and Android with Camera functionality. Once the photo has been captured the app will upload the image to the server API.
Create the app
To create the app run next command:
ionic start photo-upload-client --capacitor
then go inside it running next command:
cd photo-upload-client
Add API url to Environment file
Since our server is running locally in port 3000 it will be needed to add the API url in the environment.ts
file, so modify it with next code:
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
api: 'http://localhost:3000/' (1)
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
1 | url that points to the API server |
Add @ionic/pwa-elements
Dependency
In order to use Camera with capacitor it will be needed to add @ionic/pwa-elements
running next command:
npm i @ionic/pwa-elements
then you will need to initialize the library in the main.ts
file. To do that modify main.ts
with next code:
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { defineCustomElements } from '@ionic/pwa-elements/loader'; (1)
defineCustomElements(window); (2)
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
1 | import defineCustomElements from @ionic/pwa-elements/loader . |
2 | Call the element loader after the platform has been bootstrapped |
Modify Home page
Next step will be to modify home.page.ts
with next code:
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { CameraResultType, CameraSource, Plugins } from '@capacitor/core';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(private http: HttpClient) {}
async upload() {
const capturedImage = await Plugins.Camera.getPhoto({ (1)
source: CameraSource.Camera,
resultType: CameraResultType.DataUrl,
saveToGallery: false
});
const file = await (await fetch(capturedImage.dataUrl)).blob(); (2)
const formData = new FormData(); (3)
formData.append('file', file);
this.http.post(environment.api + 'photos/upload', formData).subscribe(resp => { (4)
console.log('resp: ', resp);
}, err => {
console.log('err: ', err);
});
}
}
1 | Gets photo using the capacitor camera plugin |
2 | converts capturedImage into blob |
3 | appends the blob file into a new formData |
4 | sends the formData to the photos/upload api with a POST request. |
then modify home.page.html
with next code:
<ion-header>
<ion-toolbar>
<ion-title>
Photo Upload
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-fab-button (click)="upload()">
<ion-icon name="camera"></ion-icon>
</ion-fab-button>
</ion-content>
Running the App
To run the app you will need to execute next command:
ng serve
this will initialize your app in localhost:4200