Alpesh Trivedi
Alpesh Trivedi

Reputation: 979

Ionic 3 - Upload Image, PDF and form data in single HTTP request

I am working on an Ionic 3 app. Where I need to upload the Image file, PDF file and form data in a single HTTP request.

I have tried Cordova file transfer plugin also but for that I have to call multiple requests (one for image and one for PDF), which I don't want to do.

I have tried each and every solution from google, but I couldn't find the right solution because each and every solution is for upload the image.

I am using PHP as backend. Please let me know where I am making the mistake.

This is HTML

<form (ngSubmit)="submitLicence()" [formGroup]="licence" enctype="multipart/form-data">
    <ion-list inset>
            <ion-item>
                <ion-label>Licence Type</ion-label>
                <ion-input type="text" formControlName="licence_type" placeholder="Value"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>State</ion-label>
                <ion-input type="text" formControlName="state" placeholder="Value"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Year</ion-label>
                <ion-input type="number" formControlName="year" placeholder="Value"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Select PDF</ion-label>
                <ion-icon name="md-add-circle" item-end color="secondary" (click)="selectPDF()"></ion-icon>
            </ion-item>
            <ion-item>
                <ion-label>Take a Photo</ion-label>
                <ion-icon name="md-add-circle" item-end color="secondary" (click)="presentActionSheet()"></ion-icon>
            </ion-item>
    </ion-list>

    <div padding> 
        <button ion-button type="submit" type="submit" [disabled]="!licence.valid" block>Submit</button>
    </div>
</form>

These functions are for upload pdf.

selectPDF(){
     this.fileChooser.open()
     .then(uri => 
           {(<any>window).FilePath.resolveNativePath(uri, (result) => {
               let loaderPdf = this.loadingCtrl.create({
                  content: "Uploading PDF..."
               });
              loaderPdf.present();
              // this.fd.append('doc',result);
              this.testResponse = result;
              this.nativepath = result;
              this.readfile(loaderPdf);
           })
     })
     .catch(e => 
       this.testResponse = 'Error - '+e);
}

readfile(loaderPdf) {
(<any>window).resolveLocalFileSystemURL(this.nativepath, (res) => {
  res.file((resFile) => {
    var reader = new FileReader();
    // reader.readAsArrayBuffer(resFile);

    reader.onloadend = (evt: any) => {
      loaderPdf.dismiss();
      var src = evt.target.result;
      src = src.split("base64,");
      var contentAsBase64EncodedString = src[1];
      var contentType = src[0].split(':');
      this.testResponse = contentType[1].replace(';','');
      contentType = JSON.stringify(contentType[1].replace(';',''));
      var fileBlob = new Blob([evt.target.result], { type: contentType});
      this.fd.append('doc',fileBlob,'doc');
      //do what you want to do with the file
    }
    reader.readAsDataURL(resFile);
  })
})
}

These functions are to select images.

public presentActionSheet() {
    let actionSheet = this.actionSheetCtrl.create({
       title: 'Select Image Source',
       buttons: [
       {
          text: 'Load from Library',
          handler: () => {
             this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
          }
       },
       {
          text: 'Use Camera',
          handler: () => {
            this.takePicture(this.camera.PictureSourceType.CAMERA);
          }
       },
       {
          text: 'Cancel',
         role: 'cancel'
       }
       ]
  });
  actionSheet.present();
}

public takePicture(sourceType) {
     let loaderImage = this.loadingCtrl.create({
       content: "Uploading Image..."
     });
     loaderImage.present();
     var options = {
       quality: 100,
       sourceType: sourceType,
       saveToPhotoAlbum: false,
       correctOrientation: true
     };
     // Get the data of an image
     this.camera.getPicture(options).then((imageData) => {
        // Special handling for Android library
        this.base64Image = imageData;
        this.readImage(loaderImage);
     }, (err) => {
        this.presentToast('Error while selecting image.');
     });
}
readImage(loaderImage) {
(<any>window).resolveLocalFileSystemURL(this.base64Image, (res) => {
  res.file((resFile) => {
    var reader = new FileReader();
    // reader.readAsArrayBuffer(resFile);

    reader.onloadend = (evt: any) => {
      var src = evt.target.result;
      src = src.split("base64,");
      var contentAsBase64EncodedString = src[1];
      var contentType = src[0].split(':');
      this.testResponse = contentType[1].replace(';','');
      contentType = JSON.stringify(contentType[1].replace(';',''));
      var imageBlob = new Blob([evt.target.result], { type: contentType});
      loaderImage.dismiss();
      this.fd.append('image',imageBlob,'image');
      //do what you want to do with the file
    }
    reader.readAsDataURL(resFile);
  })
})
}

And finally, this function is for post the form.

 submitLicence(){
     const licenceFormValue = JSON.stringify(this.licence.value);
     let loader = this.loadingCtrl.create({
       content: "Submitting form..."
     });
     loader.present();
     var lt = this.licence.value.licence_type;
     var st = this.licence.value.state;
     var yr = this.licence.value.year;
     this.fd.append('type',lt);
     this.fd.append('state',st);
     this.fd.append('year',yr);
     this.fd.append('mode','createNewLicence');    
     this.testResponse = licenceFormValue;
     let headers = new HttpHeaders();
     headers = headers.set('Content-Type', 'application/json; charset=utf-8');
     this.lic = this.httpClient.post('http://website.com/api.php',this.fd,{headers:headers});
this.lic.subscribe(data => {
     loader.dismiss();
     this.testResponse = JSON.stringify(data);
   })
}

This is PHP script to upload data and images as well.

error_reporting(0);
date_default_timezone_set('GMT'); 
require_once './config/config_live.php';
include_once PATH_FRONT_LIBRARY . 'adodb5/adodb.inc.php';
include_once PATH_FRONT_LIBRARY . "ADODBClass_mysql.php";
include_once PATH_FRONT_LIBRARY_MAILER . "phpmailer/class.phpmailer.php";
include_once PATH_FRONT_LIBRARY_MAILER . "sendEmail.php";
header('Access-Control-Allow-Origin: *');  
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content- 
Disposition, Content-Description');

if ($_POST['json']) { 
  $data = json_decode($_POST['json'], true);
} else {
  $jsonString = file_get_contents('php://input');
  $jsonObj = json_decode($jsonString, true);
  $data = $jsonObj;
}
if ($data["key"] == "difsfk") {

NOTE: The PHP API on which I am working is created by another person and I have to write ionic code as per PHP code.

Upvotes: 0

Views: 5185

Answers (1)

Sunny Shah
Sunny Shah

Reputation: 13020

have you tried with ionic native http library

please follow link : https://ionicframework.com/docs/native/http/

in body send your image and file data and other param.

post(url, body, headers)

For example :

 let body = new FormData();
body.append(‘image’, imagedata);
body.append(‘pdf’, pdfdata);
body.append(‘desc’, “testing”);

this.http.post(“Your api endpoint”, body, options).subscribe(res => {
console.log(res);
});

Upvotes: 1

Related Questions