3

I am trying to parse a JSON string from one of the fields on a record within JS and trying to display the array of items on my lightning-datatable. I am using LWC for this implementation.

JSON string:

{"students" : 
  [
    {
    "studId" : "089180000AA0091",
    "classRank": "43",
    "topped": "Biology",
    "gradeCode":"CURIOUS",
    "subjCode":"989877788" 
    },

    {
    "studId" : "089180000AA0092",
    "classRank": "44",
    "topped": "Biology",
    "gradeCode":"SCORER",
    "subjCode":"989877788"  
    }
  ]
}

LWC's JS:

childRecords = [];
toDisplay = [];
connectedCallback() {
    this.data = '';
    this.parseData = [];
    this.childRecords = [];
    this.toDisplay = [];
    getJsonString({myId:this.recordId})
    .then(result => {
        this.data= result;
        this.parseData = JSON.parse(this.data);
        this.parseData.students.forEach( recItem =>{
            console.log(recItem.studId);
            console.log(recItem.classRank);
            console.log(recItem.topped);
            this.childRecords.push(recItem);
        });
        this.childRecords.forEach(student=>{
            this.toDisplay.push(JSON.stringfy(student));
        });
    })
    .catch(error => {
        console.log('Errored out.');
    });
}

HTML

<lightning-datatable key-field="studId" data={toDisplay} columns={studColumn} 
        hide-checkbox-column data-id="student">
 </lightning-datatable>

So, here is the Columns I have right now.

const COLUMNS = [
{ label: 'StudentID', initialWidth: 180, fieldName: 'studId', type: 'text', sortable : false, wrapText: true }, 
{ label: 'Class Rank', initialWidth: 300, fieldName: 'classRank', type:'text', sortable : true ,wrapText: true, hideDefaultActions: true},  
{ label: 'Topped',initialWidth: 150, fieldName: 'topped', type:'text', hideDefaultActions: true},   
{ label: 'Grade Code',initialWidth: 155, fieldName: 'gradeCode', type:'text', wrapText: true, hideDefaultActions: true}
];

I would like to somehow wire the values I get from my parsed JSON to set the value for fieldName. If there is any better way then this approach, I would like to try it out.

6
  • Hi, are you getting values when you are consoling in for loop? May 28, 2021 at 9:09
  • Hi @ShagunSharma, Yes, I am getting the values in the console. I just updated my above code. My bad, I was trying not to post any of my actual code and missed to include the students object while iterating. May 28, 2021 at 21:40
  • Hi @ShagunSharma that suggestion didn't work well. If you have any better approach or a workable solution, please feel to provide it. Jun 1, 2021 at 14:43
  • Hi, are you declaring your variables in the class body? I can't see the declarations anywhere. Jun 1, 2021 at 18:54
  • Why do you need to change fieldName dynamically? Won't the payload structure always be the same?
    – Adrian Larson
    Jun 1, 2021 at 19:07

2 Answers 2

3
+50

You need to track your toDisplay array properly.

LWC can track scalar values like strings and integers automatically, but it can't track values INSIDE an array.

Add:

@track toDisplay = [];

OR, try assigning an whole new array to toDisplay. Create a temporary array, add all your items to that and then assign that to toDisplay when you are done with the forEach loop.

I recommend going with the second option, because you will avoid triggering a rerender cycle each time you add an item to the array.

FINALLY you are re-encoding the result as a string again - the datatable needs an array, not a string as it's datasource.

I think you will need something like this:

getJsonString({myId:this.recordId})
.then(result => {
    this.data = result;
    this.parseData = JSON.parse(this.data);
    this.toDisplay = this.parseData.students;
})
.catch(error => {
    console.log('Errored out.');
});

Notice no loop necessary - all the data is already in the correct format.

This ALL depends on the data flow. Are you receiving a JSON string for you Apex call result?

IF a string, the dataflow is this:

Call Apex -> recieve JSON string -> parse to Javascript Object -> Extract array -> Assign this array to the datatable.

IF you are getting actual array from the Apex method, then the dataflow is this:

Call Apex -> recieve Javascript Object -> Extract array -> Assign this array to the datatable.
2
  • Hi Caspar, thanks for the detailed answer. It's hard to get good resources to understand the logic (at least for a newbie like me). Thank you for putting together a great answer. Jun 1, 2021 at 19:56
  • Yes, it is definitely hard to get started - esp to work out what the component SHOULD be doing and how it should do that in a conceptual sense :) Jun 1, 2021 at 20:07
1

I am updating the code below:

JS :

    studColumn = COLUMNS
    @track toDisplay = [];

    connectedCallback() {
        getJsonString({myId:this.recordId})
            .then(result => {
                console.log(result);
                var parseData = JSON.parse(result);
                this.toDisplay=parseData.students;
                console.log(JSON.stringify(this.toDisplay));
            })
            .catch(error => {
                console.log('Errored out.');
            });
    }

HTML :

        <lightning-datatable key-field="studId" data={toDisplay} columns={studColumn} 
        hide-checkbox-column data-id="student">
        </lightning-datatable>
7
  • Hi, if I console the value of this.toDisplay after the for loop, I am getting it as [object Object],[object Object]. Also, I am getting nothing to display on my Lightning-datatable. Jun 1, 2021 at 15:43
  • I have updated the js I tried, please have a look Jun 1, 2021 at 15:58
  • What are you getting for the values within this.parseData.students.forEach(recItem => as I can see all JSON values. But, for this.childRecords.push(recItem);, it's storing [Object object]. And the same is being iterated within this.childRecords.forEach(student =>. BTW, I am fetching the JSON string from a field value of the record. Jun 1, 2021 at 16:07
  • i.stack.imgur.com/cz18h.gif I am getting something like this Jun 1, 2021 at 17:10
  • 1
    @AustinEvans I have updated both the JS and HTML above. I have removed all the extra variables and for loops. I hope this works for you. Jun 1, 2021 at 18:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .