Bikram Sao
Bikram Sao

Reputation: 61

Getting child data from a JSON object in angular

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

Answers (5)

BinaryPatrick
BinaryPatrick

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

Bikram Sao
Bikram Sao

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

Ashish Panchal
Ashish Panchal

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

Orodan
Orodan

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

Shashank Agrawal
Shashank Agrawal

Reputation: 25817

Change line from:

this.products = products['records']

to

this.products = products['products']

because the response format has the key products.

Upvotes: 0

Related Questions