Reputation: 121
My Component code:
products: Product[];
constructor(private productService: ProductService) { }
ngOnInit() {
this.productService.getProducts()
.subscribe(
(products: Product[]) => {
this.products = products;
}
);
}
My HTML Code:
<tr *ngFor="let product of products">
<td>
<a [routerLink]="['/product-details', product.SKU]">{{ product.SKU }} </a>
</td>
<td>
<a [routerLink]="['/product-details', product.SKU]">{{ product.mrp }} </a>
</td>
</tr>
My Service Code:
getProducts() {
return this.http.get('http://localhost:3000/product')
.map((response: Response) => {
const products = response.json().obj;
let transformedMessages: Product[] = [];
for (let product of products) {
transformedMessages.push(new Product(product.SKU, product.mrp, 111, 111));
}
this.products = transformedMessages;
return transformedMessages;
return products;
})
.catch((error: Response) => Observable.throw(error.json()));
My Backend route:
router.get('/', function (req, res, next) {
Product.find().exec(function (err, products) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
message: 'Success',
obj: products //obj comes from here
});
});
});
Response:
{
"message": "Success",
"obj": [
{
"0": {
"SKU": "V2620151BR",
"Batch": "1",
"Folder Number": "85",
"MRP": "799",
"Size": "Free",
"Color": "Yellow",
},
My Backend Model Class:
var schema = new Schema({
sku: { type: String, required: true, unique: true },
mrp: { type: Number }
});
My Frontend Model:
export class Product {
constructor(
public SKU: string,
public mrp: number,
public selling_price: number,
public current_inventory: number
) { }
}
My http://localhost:3000/product
reutrns the json response correctly. But somehow in the HTML, when the page loads everything is empty.
I am only getting one value - empty empty 111 111
Most of the things are setup fine, I am not sure why the empty HTML when I get the response back from http://localhost:3000/product
Upvotes: 1
Views: 3516
Reputation: 176896
I better suggest make change in your backend code and try to return json string structure like
Response:
{
"message": "Success",
"obj": [
{
"ProductId": "0",
"SKU": "V2620151BR",
"Batch": "1",
"Folder Number": "85",
"MRP": "799",
"Size": "Free",
"Color": "Yellow",
},
}
that will resolve your issue , without not much code change in front end i.e. in angular part
if you are not getting sturcture of reponse properly I sugest you make use of this potal : http://json2ts.com/ which helps to convert json string to typscript object.
for this structure given by you : { "0": { "SKU": "V2620151BR", "MRP": "799" }}
this is typescript object got created.
declare module namespace {
export interface ProductDetail{
SKU: string;
MRP: string;
}
export interface ProductRoot{
productDetail: ProductDetail;
}
}
if you have above kind of structure than your code will be as below (i havent run code at my end but if there is any error please inform it should be like that only )
getProducts() : Observable<Array<ProductDetail>>
{
return this.http.get('http://localhost:3000/product')
.map((response: Response) => {
debugger;//try to debug this part specially response returned
//for server
let resproducts:Array<ProductRoot> = response.json().obj;
let transformedMessages: ProductDetail[] = [];
for (let product of resproducts) {
transformedMessages.push(new ProductDetail(product.productDetail.SKU, product.productDetail.mrp, 111, 111));
}
return transformedMessages;
})
.catch((error: Response) => Observable.throw(error.json()));
code in component
products: ProductDetail[];
constructor(private productService: ProductService) { }
ngOnInit() {
this.productService.getProducts()
.subscribe(
(products: Product[]) => {
this.products = products;
}
);
}
i suggest not to give same name to propeties , better keep name different - try below code
I am guessing here that your server code is returning json array of product
getProducts()
{
return this.http.get('http://localhost:3000/product')
.map((response: Response) => {
debugger;//try to debug this part specially response returned
//for server
let resproducts:Array<Product> = response.json();
let transformedMessages: Product[] = [];
for (let product of resproducts) {
transformedMessages.push(new Product(product.SKU, product.mrp, 111, 111));
}
return transformedMessages;
})
.catch((error: Response) => Observable.throw(error.json()));
component code
products: Product[];
constructor(private productService: ProductService) { }
ngOnInit() {
this.productService.getProducts()
.subscribe(
(res) => {
this.products = res;
}
);
}
Upvotes: 1
Reputation: 1299
You are subscribing to the empty array in your case, because the return is executed before getting all the data. That's why it is better to use Promise
return this.http.get(url)
.toPromise()
.then((response) => {doSomething()});
If you want to keep your code, try to create an initial empty product and a real BehaviorSubject and emit the new value, then subscribe to this :
this.initialProduct = EMPTY_PRODUCT;
changeProduct: BehaviorSubject<Product or any> = new BehaviorSubject(this.initialProduct)
then just before the return this.changeProduct.emit(product);
and subscribe to the answer instead of the get function :
this.changeProduct.subscribe((product) => {doSomething()};
Upvotes: 1