Here is my Post API working greet with postman
router.post(`/`, uploadOptions.single('image'), async (req, res) =>{
const category = await Category.findById(req.body.category);
if(!category) return res.status(400).send('Invalid Category')
const file = req.file;
if(!file) return res.status(400).send('No image in the request')
const fileName = req.file.filename
const basePath = `${req.protocol}://${req.get('host')}/public/uploads/`;
let product = new Product({
name: req.body.name,
description: req.body.description,
richDescription: req.body.richDescription,
image: `${basePath}${fileName}`,
brand: req.body.brand,
price: req.body.price,
category: req.body.category,
countInStock: req.body.countInStock,
rating: req.body.rating,
numReviews: req.body.numReviews,
isFeatured: req.body.isFeatured,
})
product = await product.save();
if(!product)
return res.status(500).send('The product cannont be created')
res.send(product);
})
and this my form
<div >
<div >
<h2 >add new product </h2>
<!-- <div *ngIf="" role="alert"></div> -->
<form #addProductForm="ngForm" (ngSubmit)="SubmitData(addProductForm)">
<div >
<label for="name">Name
<sup >*</sup>
</label>
<input required name="name" id="name" #name="ngModel" ngModel type="text" >
</div>
<div >
<label for="description">description
<sup >*</sup>
</label>
<input required name="description" id="description" #description="ngModel" ngModel type="text" >
</div>
<div >
<label for="richDescription">richDescription
<sup >*</sup>
</label>
<input required name="richDescription" id="richDescription" #richDescription="ngModel" ngModel type="text" >
</div>
<div >
<label for="brand">brand
<sup >*</sup>
</label>
<input required name="brand" id="brand" #brand="ngModel" ngModel type="text" >
</div>
<div >
<label for="price">price
<sup >*</sup>
</label>
<input required name="price" id="price" #price="ngModel" ngModel type="number" >
</div>
<div >
<label for="category">category
<sup >*</sup>
</label>
<input required name="category" id="category" #category="ngModel" ngModel type="text" >
</div>
<div >
<label for="countInStock">countInStock
<sup >*</sup>
</label>
<input required name="countInStock" id="countInStock" #countInStock="ngModel" ngModel type="number" >
</div>
<div >
<label for="image">image
<sup >*</sup>
</label>
<input required type="file" name="file" #file="ngModel" [ngModel] accept="image/*">
</div>
<br>
<input type="submit" value="Add Product" [disabled]="!addProductForm.valid">
</form>
</div>
</div>
and this from component
SubmitData(form: { value: {
category: string; name: string; description: string; brand: string; richDescription: string;
price: number; countInStock: number; image: File;
}; }){
const data = {
name: form.value.name,
description: form.value.description,
richDescription: form.value.richDescription,
brand: form.value.brand,
price: form.value.price,
category: form.value.category,
countInStock: form.value.countInStock,
image: form.value.image,
};
this.productService.postData(data).subscribe(response => {
console.log(response);
});
}
product Services
import { HttpClient, HttpHeaders , HttpEvent} from "@angular/common/http";
import { Injectable } from '@angular/core';
import { Product } from "../models/Product";
import { map, Observable, switchMap, tap } from "rxjs";
@Injectable({
providedIn: 'root'
})
export class ProductService {
// jsonURL = 'assets/data.json';
warehouseURL = 'http://localhost:5000/v1/products/';
constructor(private http: HttpClient) { }
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.warehouseURL)
.pipe(
tap(data => console.log('All: ', JSON.stringify(data))),
);
}
getProduct(_id: string): Observable<Product | any> {
return this.getProducts()
.pipe(
map((products: Product[]) => products.find(p => p._id === _id)
)
)
}
RemoveProduct(_id: string){
this.http.delete<Product[]>(this.warehouseURL _id)
.subscribe(()=>{
})
}
postData(data: any): Observable<any>{
return this.http.post(`${this.warehouseURL}`, data)
.pipe(
tap(data => console.log('All: ', JSON.stringify(data))),
);
}
}
when I try to post using postman it works fine, but I cannot post data from the application it self and generates an error message "400 NO image in the request".So can you guys tell me what my mistake is? thank you very much!
CodePudding user response:
Change image input tag's name
attribute to image
instead of file
, and also, you need to add file listener, and include it to the form upon submit:
<input type="file" name="image" #image="ngModel" [ngModel] accept="image/*" (change)="onFileChange($event)">
Also, you need to prepare form-data
and send that instead of an object.
// file holder
image?: File | any;
// file listener
onFileChange(event: any) {
if (event.target.files.length > 0) {
const file = event.target.files[0];
this.image = file
}
}
construct form in the SubmitData
:
const data = new FormData();
data.append('name', form.value.name);
data.append('description', form.value.description);
data.append('richDescription', form.value.richDescription);
data.append('brand', form.value.brand);
data.append('price', form.value.price);
data.append('category', form.value.category);
data.append('countInStock', form.value.countInStock);
data.append('image', this.image);