2

I am trying to use an expansion panel to hold my data from database so that I can list the data more nicely.

I'm trying to print out my nested JSON array with an *ngFor. Problem is my JSON is nested, how will i manage to do this?

Here I am trying to print out my name and total sales in the top of the panel. After it is clicked it should then open the underpanel with my other data from the nested array.

HTML

<mat-accordion>
    <mat-expansion-panel *ngFor="let data of dataList">
        <mat-expansion-panel-header>
            <mat-panel-title>
                {{data.name}}
            </mat-panel-title>
        <mat-panel-description>
            {{data.total_sales}}
        </mat-panel-description>
    </mat-expansion-panel-header>
        {{data.sales}}
    </mat-expansion-panel>
</mat-accordion>

JSON return by my get.http function

{""
    :{"name":null,
    "total_sales":1200,
    "sales": [
    {
         "name":null,
         "masterID":"5049",
         "beerline":"2",
         "containerNo":"1",
         "pluNo":"1",
         "pluName":"Smirnoff 2cl",
         "pluDepartment":"VODKA",
         "pluPrice":"20.00",
         "sold_count":"54"
    }, 
    {
         "name":null,
         "masterID":"4028",
         "beerline":"8",
         "containerNo":"4",
         "pluNo":"1",
         "pluName":"Smirnoff 2cl",
         "pluDepartment":"VODKA",
         "pluPrice":"20.00",
         "sold_count":"1"
    },
    {
         "name":null,
         "masterID":"4028",
         "beerline":"9",
         "containerNo":"5",
         "pluNo":"3",
         "pluName":"Johnsrom",
         "pluDepartment":"rom",
         "pluPrice":"25.00",
         "sold_count":"1"
    },
    {
         "name":null,
         "masterID":"4028",
         "beerline":"10",
         "containerNo":"6",
         "pluNo":"3",
         "pluName":"Johnsrom",
         "pluDepartment":"rom",
         "pluPrice":"25.00",
         "sold_count":"1"
    },
    {
         "name":null,
         "masterID":"4028",
         "beerline":"11",
         "containerNo":"7",
         "pluNo":"3",
         "pluName":"Johnsrom",
         "pluDepartment":"rom",
         "pluPrice":"25.00",
         "sold_count":"1"
    },
    {
         "name":null,
         "masterID":"4028",
         "beerline":"12",
         "containerNo":"8",
         "pluNo":"3",
         "pluName":"Johnsrom",
         "pluDepartment":"rom",
         "pluPrice":"25.00",
         "sold_count":"1"
    }
    ]},
         "Show Room":
    {
         "name":"Show Room",
         "total_sales":4110,

 "sales":[
           {
            "name":"ShowRoom",
            "masterID":"4028",
            "beerline":"1",
            "containerNo":"1",
            "pluNo":"1",
            "pluName":"Smirnoff2cl",
            "pluDepartment":"VODKA",
            "pluPrice":"20.00",
            "sold_count":"198"
           },
           {
            "name":"ShowRoom",
            "masterID":"4028",
            "beerline":"1",
            "containerNo":"2",
            "pluNo":"3",
            "pluName":"Johnsrom",
            "pluDepartment":"rom",
            "pluPrice":"25.00",
            "sold_count":"5"
           },
           {
            "name":"ShowRoom",
            "masterID":"4028",
            "beerline":"3",
            "containerNo":"2",
            "pluNo":"3",
            "pluName":"Johnsrom",
            "pluDepartment":"rom",
            "pluPrice":"25.00",
            "sold_count":"1"
           }
           ]},
           "Henriks Place":
           {
           "name":"Henriks Place",
           "total_sales":50,
              "sales":
                      [
                        {
                         "name":"Henriks Place",
                         "masterID":"4028",
                         "beerline":"4",
                         "containerNo":"2",
                         "pluNo":"3",
                         "pluName":"Johnsrom",
                         "pluDepartment":"rom",
                         "pluPrice":"25.00",
                         "sold_count":"1"
                        },
                        {
                         "name":"Henriks Place",
                         "masterID":"4028",
                         "beerline":"6",
                         "containerNo":"3",
                         "pluNo":"3",
                         "pluName":"Johnsrom",
                         "pluDepartment":"rom",
                         "pluPrice":"25.00",
                         "sold_count":"1"
            }
        ]
     }
}

EDIT: ERROR I GET:

ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
    at NgForOf.push../node_modules/@angular/common/fesm5/common.js.NgForOf.ngDoCheck (common.js:3152)
    at checkAndUpdateDirectiveInline (core.js:9253)
    at checkAndUpdateNodeInline (core.js:10514)
    at checkAndUpdateNode (core.js:10476)
    at debugCheckAndUpdateNode (core.js:11109)
    at debugCheckDirectivesFn (core.js:11069)
    at Object.eval [as updateDirectives] (SaleComponent.html:33)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:11061)
    at checkAndUpdateView (core.js:10458)
    at callViewAction (core.js:10699)

function returning json:

getSale1(): Observable<Sale1Model[]> {
        return this.http.get<Sale1Model[]>(API_URL + '/live/sale', this.httpUtils.getHTTPHeader())

    }

EDIT 2:

This is my model class:

export class Sale1Model {

    constructor(
        public name: string,
        public total_sales: string,
        public sales: string[]) { }
5
  • I think the better solution would be change your JSON structure, but could you also show the service that get this? Commented Oct 29, 2018 at 15:00
  • @Gabax added error message and my function getting the json, what would you change the json structure to if i was going to do that? Commented Oct 29, 2018 at 15:13
  • Could you add Sale1Model class too? Anyway I'd change your JSON structure cause you have: { "": { "name": null, "total_sales": 1200, "sales": [ ] }; while it would be better something like this: { "name": null, "total_sales": 1200, "sales": [ ] } or { "data": { "name": null, "total_sales": 1200, "sales": [ ] } Commented Oct 29, 2018 at 15:17
  • @Gabax I have added my model class now. Could it be the way i am trying to state the array in model? - Can you take a look on it? Thank for helping out! Commented Oct 30, 2018 at 7:35
  • I don't see errors, but I can't understand why your first object is empty. Anyway you could try one of the answers below and see if it works. I don't know if Angular considers name of empty object, so let me know Commented Oct 30, 2018 at 8:59

2 Answers 2

1

use another *ngFor on panel body to iterate nested array

<mat-accordion>
    <mat-expansion-panel *ngFor="let data of dataList">
        <mat-expansion-panel-header>
            <mat-panel-title>
                {{data.name}}
            </mat-panel-title>
        <mat-panel-description>
            {{data.total_sales}}
        </mat-panel-description>
    </mat-expansion-panel-header>
        <div class="sale-body" *ngFor="let s of data.sales"> <sale body here> </div>
    </mat-expansion-panel>
</mat-accordion>
Sign up to request clarification or add additional context in comments.

Comments

0

just add one more *ngFor loop for nested sales array

<mat-accordion>
    <mat-expansion-panel *ngFor="let data of dataList">
        <mat-expansion-panel-header>
            <mat-panel-title>
                {{data.name}}
            </mat-panel-title>
        <mat-panel-description>
            {{data.total_sales}}
        </mat-panel-description>
    </mat-expansion-panel-header>
        <div *ngFor="let sale of data.sales">{{sale.name}}</div> // use your sale object here as you want
    </mat-expansion-panel>
</mat-accordion>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.