Reputation: 61
I'm new in angular and cloud function. I've created a cloud function to fetch data from Firebase. It is responding correctly in postman.
It's format is as follows:
{
"products": {
"-L7bnFARTPRbuYbPXnVw": {
"createdAt": "Thu Mar 15 2018 09:26:09 GMT+0530 (India Standard Time)",
"image": "https://firebasestorage.googleapis.com/v0/b/sign-up-angular.appspot.com/o/images%2Fbackground1.jpg?alt=media&token=fe96aeab-4f6f-4338-ad08-c3e0da1d610b",
"likes": 1,
"pname": "asdf",
"price": "123"
},
"-L7bnJBfADM_PFVnKo4N": {
"createdAt": "Thu Mar 15 2018 09:26:25 GMT+0530 (India Standard Time)",
"image": "https://firebasestorage.googleapis.com/v0/b/sign-up-angular.appspot.com/o/images%2Fbackground1.jpg?alt=media&token=fe96aeab-4f6f-4338-ad08-c3e0da1d610b",
"likes": 0,
"pname": "asdf",
"price": "123"
}
}
}
I want to retrieve the data and show in angular.
The angular ts & html files are as follows:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ProductService } from '../product.service';
import { Observable } from 'rxjs/Observable';
import { Product } from '../product';
@Component({
selector: 'app-data',
templateUrl: './data.component.html',
styleUrls: ['./data.component.css'],
providers: [ProductService]
})
export class DataComponent implements OnInit {
products:Product[];
constructor(private productService: ProductService) { }
ngOnInit() {
this.productService.readProducts()
.subscribe(products =>{
this.products = products['records']
console.log(products);
//On console data are showing properly.
});
}
}
HTML:
<div class="row">
<div class="col-md-12">
<!-- HTML table for our list of product records -->
<table class='table table-hover table-responsive table-bordered'>
<tr>
<th>Product</th>
<th>Price</th>
<th>Like</th>
<th>Image</th>
</tr>
<!-- Use *ngFor directive to loop throught our list of products. -->
<tr *ngFor="let product of products">
<td>{{product.pname}}</td>
<td>{{product.products.pname}}</td>
<td>{{product.price}}</td>
<td>{{product.likes}}</td>
<td>{{product.image}}</td>
</tr>
</table>
</div>
</div>
But it is showing no data.
So please help to show the data in table. Thanks in advance.
Upvotes: 1
Views: 8096
Reputation: 512
Your data is not an array and thus is not iterable. An object can only be traversed by it's fields. You could instead make a shadow array using Object.keys
and iterate through it instead. Ie:
productNames: string[];
products: Product
ngOnOnit() {
// Code to get the products and stuff
this.productNames = Object.keys(this.products);
}
And then in the HTML
<tr *ngFor="let productName of productNames">
<td>{{products[productName]}}</td>
</tr>
Upvotes: 0
Reputation: 61
Thanks everyone . I solved the problem as follows,
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { ProductService } from '../product.service';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-data',
templateUrl: './data.component.html',
styleUrls: ['./data.component.css'],
providers: [ProductService]
})
export class DataComponent implements OnInit {
products: any={};
items: any=[];
constructor(private productService: ProductService) { }
ngOnInit() {
this.productService.readProducts()
.subscribe(products =>{
this.products = products['products']
console.log((Object.values(this.products)));
this.items = Object.values(this.products);
console.log("Item data:"+this.items);
});
}
}
Upvotes: 2
Reputation: 504
There's a fine library which can be use to manipulate JSON documents and it's very small and very easy to learn and only one function to remember (jmespath.search(obj, filter)).
You can read more on it's website - http://jmespath.org/ or http://ashishuideveloper.in/2017/12/manipulate-json-document-easily-jmespath/
Upvotes: 0
Reputation: 1047
The problem comes from the fact that products is an object and not an array.
To iterate through your products with *ngFor, I would advise to convert your products in an array.
A simple way to do so is to use Object.keys() to get your products ids and construct your array something like that :
ngOnInit () {
this.productService.readProducts().subscribe(products => {
const productIds = Object.keys(products['records']);
this.products = productIds.map(productId => {
const product = products['records'][productId];
product.id = productId;
return product;
});
});
}
I imagine you still need to keep a track of your product id, so in the example I add it to the product object before adding it to your array of products.
Hope that helps
Upvotes: 0
Reputation: 25817
Change line from:
this.products = products['records']
to
this.products = products['products']
because the response format has the key products
.
Upvotes: 0