Search code examples
javascriptvue.jsquasar

Vue Quasar q-table for multiples arrays in array


I'm currently trying to show a table with a dynamic number of columns depending on the response from the API.

Here is an example of API response I have (The number of elements in the dataExportColumnsTagList can vary from 1 to many ... For this example I put 3 elements):

allData:[
{
  "id": 167831,
  "tag": "House1",
  "timestamp": "2020-12-17T00:00:00",
  "dataExportColumnsTagList": [
    {
      "element_tag": "PROD_ELEMENT",
      "display_unit_tag": "Gram",
      "value": 23,
      "index": 1
    },
    {
      "element_tag": "PROD_A",
      "display_unit_tag": "Day",
      "value": 5,
      "index": 0
    },
    {
      "element_tag": "PROD_T",
      "display_unit_tag": "Degree Celsius",
      "value": 25,
      "index": 0
    }
  ]
},
{
  "id": 167834,
  "tag": "House1",
  "timestamp": "2020-12-17T03:10:19",
  "dataExportColumnsTagList": [
    {
      "element_tag": "PROD_ELEMENT",
      "display_unit_tag": "Gram",
      "value": 22,
      "index": 1
    },
    {
      "element_tag": "PROD_A",
      "display_unit_tag": "Day",
      "value": 5,
      "index": 0
    },
    {
      "element_tag": "PROD_T",
      "display_unit_tag": "Degree Celsius",
      "value": 24,
      "index": 0
    }
  ]
}
]

I want the table to be formatted as this :

timestamp tag PROD_ELEMENT (Gram) Index PROD_A (Day) Index PROD_T (D Celsius) Index
2020-12-17 00:00:00 House1 23 1 5 0 25 0
2020-12-17 03:10:19 House1 22 1 5 0 24 0

I'm not able to iterate over the element that are repeating (dataExportColumnsTagList)...

Here is my code for now :

<template>
  <q-table style="margin-top: 16px"
    class="q-mb-sm q-ml-sm"
    :data="allData"
    :columns="columns"
    :pagination.sync="pagination"
    row-key="id"
  >
    <template v-slot:body="props">
      <q-tr :props="props">
        <q-td key="timestamp" :props="props">
            {{ props.row.timestamp.replace('T', ' ') }}
        </q-td>
        <q-td key="datasite_tag" :props="props">
          {{ props.row.datasite_tag }}
        </q-td>

        <q-td :props="props" v-for="dataExportColumnst in allData[id].dataExportColumnsTagList" :key="dataExportColumnst.datapoint_descriptor_tag">
          {{ dataExportColumnst.value }}
        </q-td>
        <q-td key="index" :props="props">
            {{ props.row.index }}
        </q-td>
      </q-tr>
    </template>
    <template v-slot:top-right>
      <q-btn
        color="primary"
        icon-right="archive"
        label="Export to csv"
        no-caps
        @click="exportTable"
      />
    </template>
  </q-table>
</template>

Solution

  • My answer here was bothering me, so here's the answer you were looking for.

    I did need to modify the columns, since I didn't know how yours is set up.

    Note: Quasar changed data property to rows and pagination.sync was changed to v-model:pagination in Vue 3. Link

    <template>
        <q-table 
            style="margin-top: 16px"
            class="q-mb-sm q-ml-sm"
            :data="allData"
            :columns="columns"
            :pagination.sync="pagination"
            row-key="id"
        >
            <template v-slot:body="props">
                <q-tr :props="props">
                    <q-td key="timestamp" :props="props">
                        {{ props.row.timestamp.replace('T', ' ') }}
                    </q-td>
                    <q-td key="tag" :props="props">
                        {{ props.row.tag }}
                    </q-td>
                    
    
                    <template v-for="row in props.row.dataExportColumnsTagList">
                        <q-td :props="props" :key="row.element_tag">
                            {{ row.value }}
                        </q-td>
                        <q-td :key="`${row.element_tag}_INDEX`" :props="props">
                            {{ row.index }}
                        </q-td>
                    </template>
                </q-tr>
            </template>
    
            <template v-slot:top-right>
                <q-btn
                    color="primary"
                    icon-right="archive"
                    label="Export to csv"
                    no-caps
                    @click="exportTable"
                 />
            </template>
        </q-table>
    </template>
    
    <script>
    export default {
        data() {
            return {
                columns: [
                    {
                        label: 'timestamp',
                        name: 'timestamp',
                        field: 'timestamp',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'tag',
                        name: 'tag',
                        field: 'tag',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'PROD_ELEMENT (gram)',
                        name: 'PROD_ELEMENT',
                        field: 'PROD_ELEMENT',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'PROD_ELEMENT_INDEX',
                        name: 'PROD_ELEMENT_INDEX',
                        field: 'PROD_ELEMENT_INDEX',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'PROD_A (Day)',
                        name: 'PROD_A',
                        field: 'PROD_A',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'PROD_A Index',
                        name: 'PROD_A_INDEX',
                        field: 'PROD_A_INDEX',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'PROD_T (D Celsius)',
                        name: 'PROD_T',
                        field: 'PROD_T',
                        align: 'center',
                        sortable: true,
                    },
                    {
                        label: 'PROD_T Index',
                        name: 'PROD_T_INDEX',
                        field: 'PROD_T_INDEX',
                        align: 'center',
                        sortable: true,
                    },
                ],
                allData: [
                    {
                        id: 167831,
                        tag: 'House1',
                        timestamp: '2020-12-17T00:00:00',
                        dataExportColumnsTagList: [
                            {
                                element_tag: 'PROD_ELEMENT',
                                display_unit_tag: 'Gram',
                                value: 23,
                                index: 1,
                            },
                            {
                                element_tag: 'PROD_A',
                                display_unit_tag: 'Day',
                                value: 5,
                                index: 0,
                            },
                            {
                                element_tag: 'PROD_T',
                                display_unit_tag: 'Degree Celsius',
                                value: 25,
                                index: 0,
                            },
                        ],
                    },
                    {
                        id: 167834,
                        tag: 'House1',
                        timestamp: '2020-12-17T03:10:19',
                        dataExportColumnsTagList: [
                            {
                                element_tag: 'PROD_ELEMENT',
                                display_unit_tag: 'Gram',
                                value: 22,
                                index: 1,
                            },
                            {
                                element_tag: 'PROD_A',
                                display_unit_tag: 'Day',
                                value: 5,
                                index: 0,
                            },
                            {
                                element_tag: 'PROD_T',
                                display_unit_tag: 'Degree Celsius',
                                value: 24,
                                index: 0,
                            },
                        ],
                    },
                ],
            };
        },
    }
    </script>