Lightning Web Components – Display [int, str], [str, str] Data from JSON to DataTable

javascriptjsonlightning-datatablelightning-web-components

I'm trying to display data from HTTP API response from third system in LWC app.

The problem is, that some of that data that I get from the external system is in following types:

enter image description here

I have trouble display the selected columns. If the returned data is just str || int .. data is properly displayed.

The mapping loop is as following:

.then(response => {
                let responseData = JSON.parse(response);
                var data = [];
                responseData.data.forEach(row => {
                  let newRow = {};
                      row.forEach((element, index) => {
                    newRow[this.columns[index].fieldName] = element;
                  });
                  data.push(newRow);
                });
                this.data_Datatable = data;
            })
            .catch(error => {
                this.error = error;
            });

WHAT I'VE TRIED:

I tried this but it doesn't work:

JSON.stringify(newRow[this.columns[index].fieldName] = element); 

Thank you.

EDIT 1 11/17/2022 – Forgot to attach datatable screenshot:

enter image description here

As you can see, I have 2 columns completely empty – those are the types that are [str, int], or [int, int] …

EDIT 2 11/17/2022 – ADDED JSON response:

    {
        "data": [
            [
                "1802523701456533",
                "701300b97e2e1000",
                "2021-03-08T03:09:57",
                [
                    1,
                    "Smartphone"
                ],
                "Galaxy S6"
            ],
            [
                "15250809629146723",
                "5957676d3b753f69",
                "2021-02-18T07:19:04",
                [
                    1,
                    "Smartphone"
                ],
                "Galaxy S6 Edge+"
            ],
            [
                "20487780899778413",
                "7a5911e7f5731400",
                "2021-01-26T15:54:48",
                [
                    0,
                    "Desktop"
                ],
                ""
            ],
            [
                "27450806533608027",
                "186af40e19b1cfdf",
                "2021-02-27T00:55:45",
                [
                    1,
                    "Smartphone"
                ],
                "iPhone"
            ],
            [
                "41195804276029081",
                "2ec0802a5c592800",
                "2021-01-22T06:33:13",
                [
                    0,
                    "Desktop"
                ],
                ""
            ], ...]
"meta": {
        "columns": [
            "session_id",
            "visitor_id",
            "timestamp",
            "device_type",
            "device_model"
        ],
        "count": 1356
    }
}

EDIT 3 11/17/2022

enter image description here

Defined outsite od LWC class:

import SystemModstamp from '@salesforce/schema/Account.SystemModstamp';

const flatten = (obj) => {
  return [...obj].map(item => {
    if (Array.isArray(item)) {
      return ('' + flatten(item)).split(',');
      }
    else {
      return '' + item
    }
  });
}

export default class mainComponent extends LightningElement {

LWC Apex imperative call –>

}).then(response => {
        let responseData = JSON.parse(response);
        console.log('responseData.data ===== \n' + responseData.data);
        this.data_Datatable = flatten(responseData.data);
      })
      .catch(error => {
        his.error = error;
      });
    }

Best Answer

Hmm how about this recursive function:

const flatten = (obj) => {
  return [...obj].map(item => {
    if (Array.isArray(item) ){
      return ('' + flatten(item)).split(',');
    }
    else {
      return '' + item
    }
  });
}

let flattened = flatten(data);

It works on each row. flatten takes the array (or object) and for each item in the array, it either appends a string (converting it to a string) or if it's still an array, it calls itself again.

To call this, define flatten outside the LWC class - as a const like above. Then invoke like this:

this.data_Datatable = flatten(responseData.data);

You'll be able to entirely skip the forEach loop that you have.


Check out a JSFiddle demonstrating this here