'Error when saving image data and form data in angular
I am implement an image upload feature to a form using multer and MEAN stack. the problem is i believe im passing the wrong set of data into the function which post the data to the server. I am unsure as to what is the correct format for the variable such that it is sent to the api server.
It returns the error:
message: 'Please upload an image' the component.html:
<div class="container">
<!--Navbar-->
<mat-toolbar color="primary">
<div class="centerNavBar">
<a mat-button href="fa-dashboard">Back</a>
<span class="headSpacer">Damage Assessment Tool</span>
<a mat-button href="">Logout</a>
</div>
</mat-toolbar>
</div>
<div>
<mat-sidenav-container class="MainContainter">
<!--SideNav-->
<mat-sidenav mode="side" opened>
<div>
<a mat-button href="">Message Board</a>
</div>
</mat-sidenav>
<mat-sidenav-content class="MainContent">
<mat-card>
<mat-card-header class="sect">Create report:</mat-card-header>
<br /><br />
<mat-card-content>
<!--Div for form-->
<div>
<form>
<mat-form-field>
<input
#MOCDateInput
matInput
type="Date"
required />
</mat-form-field>
<br />
<mat-form-field>
<mat-label>Comment</mat-label>
<input
#DescriptionInput
placeholder="--"
matInput
type="string"
required
/>
</mat-form-field>
<br />
<mat-form-field>
<mat-label>Facility In Question</mat-label>
<input
#MOCFacilityInput
placeholder="--"
matInput
type="string"
required
/>
</mat-form-field>
</form>
</div>
</mat-card-content>
</mat-card>
<mat-card>
<h3>Select Location</h3>
<mat-card-content>
<!--Div for Map-->
<div class="MOCMap">
<div class="map-container">
<div class="map-frame">
<div id="map"></div>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
<mat-card>
<mat-card-actions>
<!--Div for buttons-->
<div>
<input
style="display: none"
#ImageInput
type="file"
(change)="onFileSelected($event)"
/>
<button
mat-raised-button
type="button"
(click)="ImageInput.click()"
>
Upload Images
</button>
<button
mat-raised-button
type="submit"
(click)="
createMOCForm(
MOCFacilityInput.value,
DescriptionInput.value,
MOCDateInput.value
)
"
color="primary"
>
Submit Report
</button>
</div>
</mat-card-actions>
</mat-card>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
I believe however the problem lies in the typescript file on how i save both components, as i am using formData.append in the create function
component.ts:
import { AfterViewInit, Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormGroup, FormControl } from '@angular/forms';
import { MOCReport } from 'src/app/models/mocreport.interface';
import { MOCReportService } from 'src/app/service/mocreport.service';
@Component({
selector: 'app-moc-report',
templateUrl: './moc-report.component.html',
styleUrls: ['./moc-report.component.css'],
})
export class MocReportComponent implements OnInit
{
form: FormGroup;
mocReport: MOCReport;
imageData;
constructor(
private mocreportservice: MOCReportService,
private router: Router
) {}
onFileSelected(event) {
console.log("Select Image")
if (event.target.files.length > 0) {
const file = event.target.files[0];
this.imageData = file;
}
}
createMOCForm(
facilityName: string,
MoCDescription: string,
MoCReportDateTimeString: string
) {
//IMAGE POST
const formData = new FormData();
formData.append('mocImage', this.imageData);
const MoCReportDateTime = new Date(MoCReportDateTimeString);
this.mocreportservice
.createMOCReport(
facilityName,
MoCDescription,
MoCReportDateTime,
formData
)
.subscribe((report: MOCReport) => {
console.log(report);
this.router.navigate(['/message-board']);
});
}
ngOnInit(): void {
}}
Service Associated, service.ts:
createMOCReport(facilityName: string, MoCDescription: string, MoCReportDateTime: Date, mocImage: any){
return this.webReqService.post('MOCReport', {facilityName, MoCDescription, MoCReportDateTime, mocImage})
}
getMOCReport(){
return this.webReqService.get('MOCReport');
}
interface:
export interface MOCReport{
_id: string;
facilityName: string;
MoCDescription: string;
MoCReportDateTime: Date;
MoCDisasterLocation: Array<number>;
mocImage: File;
}
//////////////////////////////////////////////
Backend code for context:
controller (post function):
exports.MOCReport_post = (req, res, next) => {
const mocImage = req.file;
//console.log(mocImage.filename);
if(!mocImage){
const error = new Error('Please upload an image')
error.httpStatusCode = 400
return next (error)
}
let newMOCReport = new MOCReport({
facilityName: req.body.facilityName,
MoCDescription: req.body.MoCDescription,
MoCReportDateTime: req.body.MoCReportDateTime,
MoCDisasterLocation: req.body.MoCDisasterLocation,
mocImage: req.file.path
});
newMOCReport.save().then((MOCReportDoc) => {(including id)
res.send(MOCReportDoc);
});
};
Router:
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
cb(null, new Date().toISOString().replace(/:/g, '-') + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png' || file.mimetype === 'image/jpg') {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({storage: storage,
limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter: fileFilter});
router.get('/MOCReport', MOCReportController.MOCReport_get_all)
router.get('/MOCReport/:mocreportID', MOCReportController.MOCReport_get_one)
router.post('/MOCReport', upload.single('mocImage'), MOCReportController.MOCReport_post);
How can i save both the image and the form data within the same function. Any help would be appreciated. thank you in advance.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
