【发布时间】:2019-05-14 17:45:44
【问题描述】:
我需要帮助来了解如何使用 Angular 7 处理 multer (nodeJS)。 我尝试了很多不同的情况,但似乎无法上传任何文件...... 我的文件来自 ReactiveForm:
<mat-tab
label="Documents"
formGroupName="docs">
<mat-list>
<mat-nav-list>
<a mat-list-item
(click)="fsPicker.click()">
Upload financial statements
</a><input type="file" #fsPicker (change)="onDocPicked($event, 'fs')">
<a mat-list-item
(click)="cdPicker.click()">
Upload the constitutional documents
</a><input type="file" #cdPicker (change)="onDocPicked($event, 'cd')">
<a mat-list-item
(click)="idPicker.click()">
Upload the ID
</a><input type="file" #idPicker (change)="onDocPicked($event, 'id')">
<a mat-list-item
(click)="adPicker.click()">
Upload the bank account details
</a><input type="file" #adPicker (change)="onDocPicked($event, 'ad')">
</mat-nav-list>
</mat-list>
</mat-tab>
由 MimeValidator 控制:
// INSIDE NGONINIT:
this.customerForm = new FormGroup({
info: new FormGroup({
name: new FormControl(null, {validators: Validators.required}),
vat: new FormControl(null, {validators: Validators.required}),
}),
docs: new FormGroup({
fs: new FormControl(null, {asyncValidators: mimeType}),
cd: new FormControl(null, {asyncValidators: mimeType}),
id: new FormControl(null, {asyncValidators: mimeType}),
ad: new FormControl(null, {asyncValidators: mimeType})
})
});
// IN THE REST OF THE CLASS
onDocPicked(event: Event, type: string) {
const file = (event.target as HTMLInputElement).files[0];
this.customerForm.get('docs').patchValue({
[type]: file
});
this.customerForm.get('docs').get(type).updateValueAndValidity();
this.customerForm.get('docs').get(type).markAsDirty();
setTimeout(() => {
if (!this.customerForm.get('docs').get(type).valid) {
this.openAlert();
this.customerForm.get('docs').patchValue({
[type]: null
});
}
}, 100);
}
然后提交并发送到专门的服务:
onSubmit() {
if (!this.customerForm.valid) {
return;
}
this.isLoading = true;
if (!this.editMode) {
this.customerService.addCustomer(this.customerForm.get('info').value, this.customerForm.get('docs').value);
this.customerForm.reset();
} else {
const updatedCustomer: Customer = {
id: this.id,
name: this.customerForm.get('info').value.name,
vat: this.customerForm.get('info').value.vat
};
this.customerService.updateCustomer(this.id, updatedCustomer);
}
this.router.navigate(['/customers']);
}
在服务内部,处理并发送到后端:
addCustomer(info, docsData) {
const customerData = new FormData();
customerData.append('name', info.name);
customerData.append('vat', info.vat);
customerData.append('docs', docsData);
console.log(docsData);
this.http.post<{message: string, customerId: string}>(
'http://localhost:3000/api/customers',
customerData
)
.subscribe((res) => {
const customer: Customer = {
id: res.customerId,
name: info.name,
vat: info.vat
};
this.customers.push(customer);
this.customersUpdated.next([...this.customers]);
});
}
最后但并非最不重要的一点是由快递和快递公司接收和处理:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let err = new Error('invalid mime type!');
if (isValid) {
err = null;
}
cb(err, 'backend/docs');
},
filename: (req, file, cb) => {
const name = file.originalname.toLowerCase().split('').join('-');
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, name + '-' + Date.now() + '.' + ext);
}
});
const upload = multer({storage: storage});
router.post('', upload.any(),
// .fields([
// {name: 'fs'},
// {name: 'cd'},
// {name: 'id'},
// {name: 'ad'},
// ]),
(req, res, next) => {
const customer = new Customer({
name: req.body.name,
vat: req.body.vat,
});
customer.save().then(result => {
res.status(201).json({
message: 'Customer added successfully!',
customerId: result.id
});
});
});
我相信问题来自我试图发送到服务器的对象......但我不确定如何正确处理这个问题。
即使调用 multer 的 any 命令,也没有任何保存。
这里是 stackblitz 上完整项目的链接:
【问题讨论】:
标签: node.js angular express multer