Arindam Pal
Arindam Pal

Reputation: 53

Picture upload in Ionic 4 with camera and file plugins

I am trying to upload file in Ionic 4 to the server but getting the error 2nd parameter must be blob.

But I have logged the blob image it is coming properly.

I am following in this https://devdactic.com/ionic-4-image-upload-storage/ this link for the guide.

I don't need to save this to local storage so I have skipped that section.

selectImageInGallery() {
    const options: CameraOptions = {
      quality: 100,
      sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      saveToPhotoAlbum: false
    };
    this.camera.getPicture(options).then(
      imageData => {
        const formData = this.uploadAvatar(imageData);
        this.uploadAvatar(formData);
      },
      err => {
        this.toastService.presentToastBottom('Failed to select the image');
      }
    );
  }

uploadAvatar(imagePath: any) {
    let fileName = '';
    this.file
      .resolveLocalFilesystemUrl(imagePath)
      .then(fileEntry => {
        const { name, nativeURL } = fileEntry;
        const path = nativeURL.substring(0, nativeURL.lastIndexOf('/'));
        fileName = name;
        return this.file.readAsArrayBuffer(path, name);
      })
      .then(buffer => {
        const imgBlob = new Blob([buffer], {
          type: 'image/jpeg'
        });
        console.log(imgBlob);
        const formData: FormData = new FormData();
        formData.append('avatar', imgBlob);
        this.userService.updateAvatar(formData).then(res => {
          console.log(res);
          this.loader.hideLoader();
          // if (res.data.status === 'success') {
          //   this.user = res.data.user;
          // } else if (res.data.status === 'error') {
          //   this.toastService.presentToast(res.data.message);
          // } else {
          //   this.toastService.presentToast('Server Error');
          // }
        });
      });
  }

Service
public async updateAvatar(postData: any) {
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'multipart/form-data',
        'X-Authorization': environment.appKey,
        Authorization: localStorage.getItem('TOKEN_KEY')
      })
    };
    const res = await this.http
      .post(
        environment.apiUrl + 'user/update-profile-picture',
        postData,
        httpOptions
      )
      .toPromise();
    return res as any;
  }

Upvotes: 3

Views: 1827

Answers (2)

Arindam Pal
Arindam Pal

Reputation: 53

    uploadBase64(imageBase64: any) {
    this.loader.showLoader();
    const blobImg = this.dataURItoBlob(imageBase64);
    const formData: FormData = new FormData();
    formData.append('avatar', blobImg, 'image.jpeg');
    this.profileService.updateAvatar(formData).then(res => {
      this.loader.hideLoader();
      if (res.data.status === 'success') {
        this.user.avatar = imageBase64;
      } else if (res.data.status === 'error') {
        this.toastService.presentToast(res.data.message);
      } else {
        this.toastService.presentToast('Server Error');
      }
    });
  }

  dataURItoBlob(dataURI: any) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    let byteString: any;
    if (dataURI.split(',')[0].indexOf('base64') >= 0) {
      byteString = atob(dataURI.split(',')[1]);
    } else {
      byteString = unescape(dataURI.split(',')[1]);
    }
    // separate out the mime component
    const mimeString = dataURI
      .split(',')[0]
      .split(':')[1]
      .split(';')[0];
    // write the bytes of the string to a typed array
    const ia = new Uint8Array(byteString.length);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ia], { type: mimeString });
  }

  async openCertificateUploadPage() {
    const modal = await this.modalCrtl.create({
      component: CertificateUploadPage
    });
    modal.onDidDismiss().then(res => {
      this.getProfile();
    });
    return await modal.present();
  }

That is the solutions for that issue. I have figure out.

Upvotes: 0

rtpHarry
rtpHarry

Reputation: 13125

How closely have you followed this tutorial?

As I recall from watching Simon's videos (devdactic author), there are complications working with images where you need to create at least a temporary file on the system to send off to other places.

First, you should follow the tutorial exactly and then once it is working you can experiment with removing things.

In the first section of the tutorial it clearly states:

  • Upload files from their local path using a POST request

So I don't think just removing chunks of the tutorial is your best technique for getting this going.

Learn from the expert first, modify later.

Upvotes: 1

Related Questions