How to Upload files on NodeJS Server Using Multer and Native File Transfer Plugin in Ionic 3

Welcome back guys, This post shows you How to Upload files on NodeJS Server Using Multer and Native File Transfer Plugin in Ionic 3. From our last post i was really excited to write a new post on working with NodeJS. As in the last post Integrating NodeJS server into an Ionic Application , we learned pretty much about NodeJS but now is the time for some serious action.
Uploading various format of files from the front end are pretty much useless without the API on the backend to receive them and save them, so here we are!
First things first lets talk about Multer.

Multer

Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. It is written on top of busboy for maximum efficiency.
Multer adds a body object and a file or files object to the request object. The body object contains the values of the text fields of the form, the file or files object contains the files uploaded via the form.
Multer works on the Express.
as from our previous post we discussed how to integrate ionic with NodeJS so moving further To easily setup file uploading in an Ionic application with Express.js server we can use Multer.js.

Native File Transfer Plugin

This plugin allows you to upload and download files.
This plugin defines global FileTransfer, FileUploadOptions constructors. Although in the global scope, they are not available until after the deviceready event.
The FileTransfer object provides a way to upload files using an HTTP multi-part POST or PUT request, and to download files.

Create an ionic 3 project and install File and File transfer plugin.

 $ ionic cordova plugin add cordova-plugin-media
 $ npm install --save @ionic-native/media
 $ ionic cordova plugin add cordova-plugin-file
 $ npm install --save @ionic-native/file
 $ ionic cordova plugin add cordova-plugin-file-transfer
 $ npm install --save @ionic-native/file-transfer

add this plugins to the app.module.ts and import the providers.

import { FileTransfer, FileUploadOptions, FileTransferObject } from '@ionic-native/file-transfer';
import { File } from '@ionic-native/file';
import { Media, MediaObject } from '@ionic-native/media';

Creating Home.ts file for the setting up the upload options.
src/pages/home/home.ts

import { FileTransfer, FileUploadOptions, FileTransferObject } from '@ionic-native/file-transfer';
 import { File } from '@ionic-native/file';
 import { Media, MediaObject } from '@ionic-native/media';

Adding variable before constructors for holding audio

 recording: boolean = false;
 filePath: string;
 fileName: string;
 audio: MediaObject;
 audioList: any[] = [];

Add this function to get the audio

createAudio(){
 if (this.platform.is('android')) {
 this.fileName = 'record'+'-'+new Date().getFullYear()+'-'+new Date().getMonth()+'-'+new Date().getDate()+'-'+new Date().getHours()+'-'+new Date().getMinutes()+'.mp3';
 this.filePath = this.file.externalDataDirectory.replace(/file:\/\//g, '') + this.fileName;
 this.audio = this.media.create(this.filePath);
 }
 this.audio.startRecord();
 }
 audioFile(){
 this.audio.stopRecord();
 let data = { filename: this.fileName };
 this.audioList.push(data);
 this.upload();
 }

Add this function to upload the audio to the server

upload(){
 var name = "upload";

let option: FileUploadOptions = {
 fileKey:'file',
 mimeType:'audio/mp3',
 httpMethod:'POST',
 fileName:this.fileName
 };

const fileTransfer:FileTransferObject = this.transfer.create();
 console.log('filename = '+this.fileName);
 fileTransfer.upload(this.filePath, encodeURI('http://192.168.1.5:3000/upload'),option).then((result)=>
 {
 console.log("result = ", result)
 console.log('success');
 }).catch(error=>{
 // this.loader.dismiss();
 console.log('upload error');
 console.log(error);
 console.log("upload error source " + error.source);
 console.log("upload error target " + error.target);
 });
 }

Add android and run the application.

ionic cordova platform add android
ionic cordova run android

Now We Start by installing required node dependencies on server folder:

Installation:

npm init
npm install -S express multer body-parser cors path

the package.json file will look like this

server/package.json:

{
  "name": "app-name",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "express": "^4.16.2",
    "multer": "^1.3.0",
  }
}

Now modifying server.js
server/server.js

var express = require("express");
 var bodyParser = require('body-parser');
 var cors = require('cors');
 var path = require('path');
 var multer = require('multer');

var app = express();
 app.use(bodyParser.json());
 app.use(cors());

Multer adds a body object and a file or files object to the request object.
Multer accepts an options object, the most basic of which is the dest property, which tells Multer where to upload the files. In case you omit the options object, the files will be kept in memory and never written to disk.

var upload = multer({ dest: 'uploads/' })

.single(fieldname)
Accept a single file with the name fieldname. The single file will be stored in req.file.

 var upload = multer({ storage: Storage }).single('file');
var Storage = multer.diskStorage({
 destination: function(req, file, callback) {
 var pathname = file.originalname.split('#');
 var path = pathname[0].replace('_','/');
 cb(null,'./uploads'+path);// null,upload_path
 },
 filename: function(req, file, callback) {
 var pathname = file.originalname.split('#');
 var filename = pathname[1];
 if(filename!=undefined)
 callback(null, filename);
 }
 });

In DiskStorage there are two options available, destination and filename. They are both functions that determine where the file should be stored.

destination is used to determine within which folder the uploaded files should be stored. This can also be given as a string (e.g. ‘/server/uploads’). If no destination is given, the operating system’s default directory for temporary files is used.

Now finally uploading the file to server.

app.post('/upload', multer({dest:'./uploads/'}).single('file'), function(req,res)
 {
 console.log("post result ==",res.json);
 console.log("post Req file == ",req.file)
 res.json('Audio uploaded');
 });

Note, that the dest parameter is relative to the server root folder, that is where the server.js is located.

Finally, start listening

var port = 3000;
app.listen( port, function(){ console.log('listening on port '+port); } );

Now run the server, go to terminal run

node server.js

or

npm start

Test it by uploading a file and find the uploaded file in the uploads folder. Multer will rename the file to a unique name to prevent collisions, so you will want to save the data from the req.files to your data store.

Leave a Reply

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