I am new to Angular. Here, I was trying to add an object to a db and to display it in template simultaneously.
app.component.ts
export class AppComponent implements OnInit {
title = 'HttpRequest';
allProducts: Product[] = [];
@ViewChild('productsForm')
form!: NgForm;
constructor(private http: HttpClient) {}
ngOnInit() {
this.fetchProducts();
}
onProductsFetch() {
this.fetchProducts();
}
onProductCreate(products: { pName: string; desc: string; price: string }) {
console.log(products);
let header = new HttpHeaders({ myHeader: 'sachin' });
this.http
.post<{ name: string }>(
'*****',
JSON.stringify(products),
{ headers: header }
)
.subscribe({
next: (res) => {
// console.log(res);
},
});
//--------------------Error is here-----------------------------------------
//! This is not working
this.onProductsFetch();
//! This is working
// setTimeout(() => {
// this.onProductsFetch();
// }, 1000);
//--------------------Error is here-----------------------------------------
}
private fetchProducts() {
this.http
.get<{ [key: string]: Product }>(
'*****'
)
.pipe(
map((res) => {
let products: Product[] = [];
for (const [key, value] of Object.entries(res)) {
products.push({ ...value, id: key });
}
return products;
})
)
.subscribe({
next: (products) => {
this.allProducts = [...products];
console.log(this.allProducts);
},
});
}
}
app.component.html
<div >
<div >
<div >
<h1>Manage Products</h1>
<hr />
</div>
<div >
<!--Add product form-->
<div >
<h3>Create Product</h3>
<form
#productsForm="ngForm"
(ngSubmit)="onProductCreate(productsForm.value)"
>
<label>Procuct Name</label>
<input type="text" name="pName" ngModel />
<label>Procuct Description</label>
<input type="text" name="desc" ngModel />
<label>Procuct Price</label>
<input type="text" name="price" ngModel />
<input type="submit" value="Add Product" />
</form>
</div>
<!--Display product area-->
<div >
<h3>All Products</h3>
<table id="products">
<tr>
<th>#</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th></th>
<th></th>
</tr>
<tr *ngFor="let prod of allProducts; let i = index">
<td>{{ i 1 }}</td>
<td>{{ prod.pName }}</td>
<td>{{ prod.desc }}</td>
<td>${{ prod.price }}</td>
</tr>
</table>
<hr />
<div >
<button (click)="onProductsFetch()">
Refresh Products
</button>
</div>
</div>
</div>
</div>
</div>
products.model.ts
export class Product {
pName!: string;
desc!: string;
price!: string;
id?: string;
}
So here, when i use onProductCreate() method, the POST method is working but onProductFetch() isnt working and the template is not updating while if we use setTimeout(), its working completely and also template got updated. Why its happening like that?
PS: Please forgive me if my question is wrong :)
CodePudding user response:
http.post
just returns observable immidiately and does not wait your POST get response.
You have to put your this.onProductsFetch();
in subscribe
.
this.http
.post<{ name: string }>(
'******',
JSON.stringify(products),
{ headers: header }
)
.subscribe({
next: (res) => {
// console.log(res);
this.onProductsFetch();
},
});