Upload files without file transfer plugin

#1

Hi,
I’m trying to upload files from my ionic 3 app, but since the file transfer plugin is deprecated, is there a way to upload files with angular’s Http @angular/http?

Here is my current code:

  //this variable stores the image path that I need to upload
  lastImage: string = null;
  //...

  //a button in my html calls this function
  public takePicture(sourceType) {
    // Create options for the Camera Dialog
    let options = {
      quality: 100,
      sourceType: sourceType,
      saveToPhotoAlbum: false,
      correctOrientation: true
    };

    // Get the data of an image
    this.camera.getPicture(options).then((imagePath) => {
      // Special handling for Android library
      if (this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
        this.filePath.resolveNativePath(imagePath)
          .then(filePath => {
            let correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
            let currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
            this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
          });
      } else {
        let currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
        let correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
        this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
      }
    }, (err) => {
      this.presentToast('Error');
    });
  }

  private createFileName() {
    return new Date().getTime() + ".jpg";
  }

  private copyFileToLocalDir(namePath, currentName, newFileName) {
    this.file.copyFile(namePath, currentName, cordova.file.dataDirectory, newFileName).then(success => {
      this.lastImage = newFileName;
    }, error => {
      this.presentToast('Error saving the image');
    });
  }

When I take a picture I have the lastImage variable with the path of the image that I need to upload.
So, how can I send the image with an @angular/http post request?

#2

vcarvalho0402, you could use angular new HttpRequest


      function retrieve_file() {
        const req = new HttpRequest('POST', uri, context.storage, {
          reportProgress: true,
          responseType: 'arraybuffer'
        });
        let transfer = context.httpClient.request(req).retry(2).subscribe(event => retrieveEvent(event),
          (err: HttpErrorResponse) => retrieveCatch(err));

        function retrieveEvent(event) {
          {
            if (event.type === HttpEventType.DownloadProgress) {
              if (context.download_id == model_ext_id) {
                context.events.publish("updater:download", {progress: Math.round(((event.loaded / event.total) * 100))});
              }

            } else if (event instanceof HttpResponse) {
              let file = new Blob([event.body], {type: 'application/x-zip-compressed'});
              context.file.writeFile(context.settingsProvider.storage, "", file).then(() => {
                context.success_retrieve(uri, fn, model_ext_id, needDownloadFullResources, keys).then(() => resolve()).catch(err => reject(err));
              }).catch(err => {
                console.log(err);
                reject();
              })
            }
          }
        }

        function retrieveCatch(err) {
          {
            context.download_id = 0;
            if (err.error instanceof Error) {
              // A client-side or network error occurred. Handle it accordingly.
           
            } else {
              // The backend returned an unsuccessful response code.
              // The response body may contain clues as to what went wrong
            }

     
            }
            else {
             
            }
          }
        }
      }
#3

Hey vcarvalho0402,

do you have a working example with the @ionic-native/camera plugin and uploading without the transfer plugin? I’m struggling with this because I only have the file path to the picture like in your example and I cannot get this working with angular to send it to my s3 endpoint.

With the deprecated plugin I’m using the following:

let imageData = await this.camera.getPicture(options);
const timestamp = new Date().getTime();
if (this.platform.is('ios')) {
    this.imgURI = normalizeURL(imageData) + '?' + timestamp
} else {
    this.imgURI = imageData
}

...
...

const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
    fileKey: 'file',
    mimeType: 'image/jpeg',
    chunkedMode: false
};

options.params = awsCredentialData.formData;

await fileTransfer.upload(this.imgURI, awsCredentialData.url, options);

Thanks in advance
Mike

#4

Hi @Mike1707,

this is an example that I extracted from my code. It’s working for both Ios and Android platforms:

2 Likes
#5

you can use plain javascript technique as bellow

var formData = new FormData();
var blob = new Blob(['Lorem ipsum'], { type: 'plain/text' });
formData.append('file', blob,'readme.txt');

var request = new XMLHttpRequest();
request.open('POST', 'http://example.org/upload');
request.send(formData);
#6