Edit, original question has been resolved as to why file was converted to string. The code has been edited to reflect these corrections. The API handler is now outputting object as data type and buffer as the value of request.payload.file.
I'm using Aurelia to make a Single Page App. There is a HTML form that accepts two input fields, one for a file, one for text. These fields are bound to variables (selecetdImage and title) in an associated TypeScript view model. In the viewmodel they are used as arguments in a function that appends them to formData and sends a http post request with the formData to an Node/js Hapi framework API handler.
When I console.log(typeof(selectedImage) in the Aurelia app, it states object, but when I console log typeOf(selecetdImage) in the handler, I get String. I'm guessing this is why my function isn't working and giving 500 error messages
The handler itself works. I used it in a MVC server based web app. In that context, HTML form triggers a post request, and the MVC handler successfully receives the file, writes it to local/temp.img and uploads it to cloudinary. But with the API version, where I assembled the form data myself as above, the file isn't written to local/temp.img and the cloudinary upload fails.
Edit. I changed the viewmodel variables to title = null; files = null;
and I changed the formData append function to:
formData.append('file', File, files[0]);
As per the example here. The code below is now modified to match this update.
Now when I console log the value of file in the API handler, the output is:
<Buffer ff d8 ff e0 00 10.......
I'm not sure what to do with this data. I assume it's the image binary data in octal? And if so, does anyone know how to write it as an image in node? The payload is no longer of type string, now it's type object.
<form submit.delegate="uploadPhoto()" enctype="multipart/form-data">
<div class="two fields">
<div class="field">
<label>File</label>
<input type="file" name="file" accept="image/png, image/jpeg" files.bind="files">
</div>
<div class="field">
<label>Title</label> <input value.bind="title">
</div>
</div>
<button type="submit"> Upload </button>
</form>
//photoUpload.ts// (view model associated with above html
@inject(POIService)
export class PhotoForm {
@bindable
photos: Photo[];
title = null;
files = null;
constructor (private poi: POIService) {}
uploadPhoto() {
const result = this.poi.uploadPhoto(this.title, this.files);
console.log(this.title);
console.log(result);
}
//POIService (where contains injected function to create HTTP request
async uploadPhoto(title: string, files){
console.log("now uploading photo for: " + this.currentLocation)
let formData = new FormData();
formData.append("title", title);
formData.append("location", this.currentLocation); //don't worry about this variable, it's set by another function every time a page is viewed
formData.append("file", files[0]);
const response = await this.httpClient.post('/api/locations/' + this.currentLocation + '/photos', formData);
console.log(response);
}
//API Handler (accepts HTTP request, writes the image to a local folder, the uploads to cloudinary and returns the url and photo_id which are stored in a Mongod document
create: {
auth: false,
handler: async function(request, h) {
const photo = request.payload.file;
await writeFile('./public/temp.img', photo);
const result = await cloudinary.v2.uploader.upload('./public/temp.img', function(error, result) {
console.log(result)
});
const newPhoto = new Photo({
title: request.payload.title,
url: result.url,
public_id: result.public_id,
location: request.params.name
})
await newPhoto.save();
return newPhoto;
}
},
Is it a very long string, containing "data:b64" in the first 15 or so characters? If so, that means it's the base64 data.