0

I am trying to iterate over objects of object

Here is response json I will get

    { 
     "123445": {
      "displayName": "abcd",
      "items": [
        {
          "id": "e7363730-552d-4943-a3b8-082db653fc16",
          "name": "xyz",
          "displayName": "xyd",
          "price": "75",
          "quntity": "100"
        },
        {
          "id": "302fda08-502d-4f5a-98b8-cbca34f8e186",
          "name": "pqr",
          "displayName": "pqr",
          "price": "60",
          "quntity": "100"
        }

      ]
    }
}

Here is what am trying

<div *ngFor="let key of generateKeys(products | async)">
    <div *ngFor="let product of products[key].items | async">{{ product | json}}</div>
</div>

and here is funtion which will return keys from products object

  generateKeys(obj) {
    return obj ? Object.keys(obj) : null
  }

But while rendering HTML template it is giving err that

Cannot read property 'items' of undefined

Am I missing something, please suggest.

24
  • 1
    Your productsList is an object now not an array if you want an array make: productsList = [{object1},{object2},{and so on}] Commented Oct 12, 2017 at 7:02
  • @Swoox, he used Object.keys which returns an array :) Commented Oct 12, 2017 at 7:03
  • @Alexandru-IonutMihai Will return an array of object keys but still productsList is an object you can't *ngFor on it. Commented Oct 12, 2017 at 7:05
  • @Swoox, no. generateKeys returns an array then he iterate products[key].items which is an array. Commented Oct 12, 2017 at 7:06
  • @Swoox yes I have use Object.keys to get keys. For better naming I have change variable name productList to products Commented Oct 12, 2017 at 7:06

2 Answers 2

1

Based on my understanding you can try this

template

<ng-container *ngIf="products | async as products">
    <div *ngFor="let key of generateKeys(products)">
        <span>{{key}}</span>
        <div *ngFor="let product of getProducts(products,key)">
            <span>{{product.id}}</span>
        </div>
    </div>
</ng-container>

the function generateKeys will returns keys from object

 generateKeys(obj) {
    return obj ? Object.keys(obj) : null
  }

and function getProducts will return items from products

 getProducts(productsList, key: string) {
    return key ? productsList[key].items : null
  }

hope this will resolve your issue.

Sign up to request clarification or add additional context in comments.

Comments

1
import 'rxjs/add/operator/share';

@Component({...})
export class FooComponent{
 products$: Observable<{[id:string]:any}>;

 constructor(private _fooService: FooService){
   this.products$ = _fooService.getProducts().share(); //set observable
 }

  get keys$(){
    return this.products$
    .map(map => Object.keys(map));
  }

  getProducts$(key:string){
    // TODO check key existence
    return this.products$
     .map(map => map[key])
     .map(obj => obj.items || [])
  }
}

<div *ngFor="let key of keys$ | async">
    <div *ngFor="let product of getProducts$(key) | async">{{ product | json}}</div>
</div>

Another, less rjxs oriented approach, would be:

@Component({...})
export class FooComponent{
 products$: Observable<{[id:string]:any}>;

 constructor(private _fooService: FooService){
   this.products$ = _fooService.getProducts(); //set observable
 }

  getKeys(map: any): string[]{
    let result = [];
    if(map){
      result = Object.keys(map); 
    }
    return result;
  }

  getProducts(key:string,map: any): any[] {
    let result [];
    if(map & map[key]){
     result = map[key];
    }
    return result;
  }
}

<ng-container *ngIf="products$| async as products">
  <div *ngFor="let key of getKeys(products)">
    <div *ngFor="let product of getProducts(key,products)">{{ product | json}}
    </div>
   </div>
</ng-container>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.