I want to implement post file and Json data in the same request .
below is the upload file code :
upload(url:string,file:File):Observable<{compl
The way my manager @Jesse come up with is like:
public uploadFiles(id: ServerID, brd: File, sch: File, args: any[]): Observable<Blob> {
const data = new FormData();
data.append('brd', brd);
data.append('sch', sch);
data.append('data', JSON.stringify(args));
return this.httpClient.post(URL, data, {
responseType: 'blob',
});
}
The definition of the FormData append()
is append(name: string, value: string | Blob, fileName?: string): void;
which allows you to append JSON parameters to it or upload a file.
//app.component.html
<input type="file" name="file" (change)="onChange($event)">
<button (click)="onSubmisson()" [disabled]="file==null" >Submit</button>
//app.component.ts
file:File = null;
onChange(event){
this.file = event.target.files[0]
}
onSubmisson(){
this._auth.uploadFileAndData(this.file).subscribe(
res => {
console.log(res);
},err => {
console.log(err);
});
}
//upload.service.ts
uploadFileAndData(file){
var test = {test:"test"}
const formData = new FormData();
formData.append('data', JSON.stringify(test));
formData.append('file', file, file.name);
return this._http.post<any>(this._uploadurl, formData);
}
//node server
var multer = require('multer');
var path = require('path');
var storage = multer.diskStorage({
// destination
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({ storage: storage }).array("file", 12);
router.post("/upload", function(req , res){
upload(req, res, function (err) {
if(err){
console.log(err);
}else{
console.log(req.body);
console.log('files', req.files);
}
})
res.status(200).send({});
});
// output
{ data: '{"test":"test"}' }
files [ { fieldname: 'file',
originalname: 'acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './uploads/',
filename: 'acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg',
path: 'uploads\\acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg',
size: 49647 } ]
So I've been trying to do that too, and for something which look really simple I ended up with a lot of trouble to figure out a solution. Hopefully some coworkers helped me and we came up with something reasonable.
This documentation helped us a lot: https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
And here's the Angular code:
class SomeService {
someMethod(fileToUpload: File, name: string, version: string) {
const formData: FormData = new FormData();
formData.append('file', fileToUpload, fileToUpload.name);
const overrides = {
name,
version,
};
const blobOverrides = new Blob([JSON.stringify(overrides)], {
type: 'application/json',
});
formData.append('overrides', blobOverrides);
const req = new HttpRequest('POST', `some-url`, formData);
return this.http.request(req);
}
}
As @Supamiu said, using Blob was the key, and here's an example how to do that.
The below client and service code works fine in my solution, check if this helps
Client Side Code:
AddModelData(modelData: ModelData, file: any): Observable<any>
{
let urlPath = 'api/SampleActionMethod/AddModelData';
const mData = JSON.stringify(modelData);
const formData = new FormData();
formData.append('data', mData);
if (file) {
formData.append('file', file, file.name);
}
return this._http.post(this.settings.apiEndPoint + urlPath, formData);
}
Service Side Code:
public IActionResult PostMethod(IFormFile file)
{
try
{
var modelData = JsonConvert.DeserializeObject<ModelData>(Request.Form["data"]);
//data is the key that is being passed from client side
//file in params will have the posted file
//Do Something with data and file......
return Ok();
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}