Search code examples
angulartypescriptfilehttpnativescript

Angular 10 + Nativescript Multipart File Upload


I'm trying to upload a file from a phone file system using Nativescript 7. I've tried both nativescript-background-http and nativescript-http-formdata aswell as HttpClient imported from @angular/common/http but none of this methods seem to work. My server is running RocketChat (this is the API) and i can successfully upload files using Insomnia REST Client. This is my first try with Angular HttpClient:

const formData = new FormData();
var file = this._audioFolder.getFile("file.mp3");
formData.append("file", file, "file.mp3");
this.httpClient.post<any>("https://myserver.com/api/...", formData, {
  headers: {
    "X-Auth-Token": "my_token",
    "X-User-Id": "my_id",
    "Content-Type": "multipart/form-data; boundary=---011000010111000001101001"
  }
}).subscribe((resp) => {
  console.log(resp);
}

Which returned the error: Argument of type 'File' is not assignable to parameter of type 'string | Blob' when I appended file to formData. Then I tried to convert my file to Blob using this code:

getBase64String(file: fs.File) {
  const data = file.readSync();
  //data.base64EncodedStringWithOptions(0); iOS
  return android.util.Base64.encodeToString(data, android.util.Base64.NO_WRAP);
}

And then

const blob = new Blob([base64file], {type: "audio/mp3"});
formData.append("file", blob, "file.mp3");

Which was accepted by the FormData append method, but the response returned the error:

"error": {
    "success": false,
    "error": "File required"
}

Then found this solution on GitHub and was interested on this part:

formData.append('file', {
  uri: fileInfo.path,
  type: fileInfo.type,
  name: encodeURI(fileInfo.name) || 'fileMessage'
});

But returned the error: Argument of type '{ uri: string; type: string; name: string; }' is not assignable to parameter of type 'string | Blob'.

My guess is that the class File derived from nativescript/file-system is quite peculiar and can't be considered as Blob. I've also tried to convert it into buffer array using atob function, but the method is undefined.

After that, I've installed nativescript-background-http and followed this example, but i got an error here:

var task = session.uploadFile(file, request);

telling me that an instance of Observable cannot be invoked without new. The very same happens with nativescript-http-formdata on that line:

let fd = new TNSHttpFormData();

which is quite confusing since it's a very basic operation and everyone who use this plugin must instantiate that class.

Now, what else can I try to fix/workaround those problems? I can't modify the backend APIs, but I can try any method you can think of to upload a simple file using http post.


Solution

  • Finally I found a solution: as written here, if you are using Nativescript 7 you have to run

    tns plugin add @nativescript/background-http
    

    instead of

    tns plugin add nativescript-background-http
    

    Surprisingly, it's not mentioned on the official npmjs page.