1

first time posting here. I'm working on only my 2nd ever LWC. The org I'm working in has the "Related Contacts" feature enabled so they can have desired contacts set with a "Role" such as "Decision Maker". I'm working on a Lightning Web Component that will provide a simple static datatable of those related contacts that have a Role assigned. I've got everything working beautifully, except for one thing...

The datatable is not displaying the Roles data.

I know the SOQL query in the Apex controller works because I tested it in Workbench before trying to implement it. I'm thinking that the issue is in the JS file, in how I'm referencing the AccountContactRelations.Roles field for the datatable. Can anyone help me get this last piece working?

My HTML file:

<template>
  <div class="slds-box slds-theme_default">
    <lightning-card>
      <h3 slot="title" class="slds-text-title_bold">
        <lightning-icon
          icon-name="standard:client"
          size="small"
        ></lightning-icon>
        <span class="slds-m-left_small"
          >Key Account Contacts</span
        >
      </h3>

      <lightning-layout>
        <lightning-layout-item size="12">
          <lightning-datatable
            key-field="id"
            data={data}
            columns={columns}
            is-loading={tableLoadingState}
          >
          </lightning-datatable>
        </lightning-layout-item>
      </lightning-layout>
    </lightning-card>
  </div>
</template>

My JavaScript file:
(updated per manjit5190's comment)

import { LightningElement, api, track, wire } from "lwc";
import getContacts from "@salesforce/apex/keyAccountContactsController.getContacts";

const columns = [
  { label: "Role", fieldName: "Roles" },
  { label: "Name", fieldName: "Name" },
  { label: "Title", fieldName: "Title" },
  { label: "Phone", fieldName: "Phone", type: "phone" },
  { label: "Email", fieldName: "Email", type: "email" }
];

export default class KeyAccountContacts extends LightningElement {
  @api recordId;
  @track data = [];
  @track columns = columns;
  @track tableLoadingState = "true";

  @wire(getContacts, { accountId: "$recordId" })
  wiredRecordsMethod({ error, data }) {
    if (data) {
      this.data = data;
      this.error = undefined;
    } else if (error) {
      this.error = error;
      this.data = undefined;
    }
    this.tableLoadingState = false;
  }

  let result = JSON.parse(JSON.stringify(data));
  this.data = result.map(function(item) {
    item.Roles = "";
    item.AccountContactRelations.forEach(element => {
      item.Roles += element.Roles + ", ";
    });
    return item;
  })

}

My Apex Controller file:

public with sharing class keyAccountContactsController {

    @AuraEnabled(cacheable=true)
    public static List<Contact> getContacts(String accountId) {
        return [SELECT Name, Title, Email, Phone,
                    (SELECT Roles FROM AccountContactRelations WHERE Roles <> NULL) Roles
                  FROM Contact
                  WHERE Id In (SELECT ContactId FROM AccountContactRelation WHERE Roles <> NULL)
                    AND AccountId = '0017000000R8lzTAAR'
                  LIMIT 5];
    }
}

And a screenshot of the final result:
(note the empty "Roles" column)
(and yes, I know for a fact that the listed contact has a Role assigned in the junction object) lightning web component rendered on the page // notice the blank "Roles" column

1

Jarod, the AccountContactRelations is returning an array and based on the column definition, you are looking for a text/String.

You may need to do manipulation either in your Apex controller or JS.

I have used the JS array.map function here which returns a new array after executing the function provided as an argument to it on each item.

JS:

import { LightningElement, api, track, wire } from "lwc";
import getContacts from "@salesforce/apex/keyAccountContactsController.getContacts";

const columns = [
  { label: "Role", fieldName: "Roles" },
  { label: "Name", fieldName: "Name" },
  { label: "Title", fieldName: "Title" },
  { label: "Phone", fieldName: "Phone", type: "phone" },
  { label: "Email", fieldName: "Email", type: "email" }
];

export default class KeyAccountContacts extends LightningElement {
  @api recordId;
  @track data = [];
  @track columns = columns;
  @track tableLoadingState = "true";

  @wire(getContacts, { accountId: "$recordId" })
  wiredRecordsMethod({ error, data }) {
    if (data) {
       let result = JSON.parse(JSON.stringify(data));
        this.data = result.map(function(item) {
          item.Roles = "";
          item.AccountContactRelations.forEach(element => {
            item.Roles += element.Roles + ", ";
          });
          return item;
        })
      this.error = undefined;
    } else if (error) {
      this.error = error;
      this.data = undefined;
    }
    this.tableLoadingState = false;
  }
}

And column definition as:

const columns = [
    { label: "Role", fieldName: "Roles" },
    { label: "Name", fieldName: "Name" },
    { label: "Title", fieldName: "Title" },
    { label: "Phone", fieldName: "Phone", type: "phone" },
    { label: "Email", fieldName: "Email", type: "email" }
];
| improve this answer | |
  • I'd wondered about that. I plugged the new let result... block into my JS file but VS Code is reporting problems. I'm a JS learner, so I'm not sure what I'm looking at. Any chance you can see the problem? (updated my initial post to reflect the new JS contents) – jarod Mar 16 at 7:54
  • Apologies if it wasn't clear but the JS code provided was supposed to go inside wire. I have added the complete js file now. – manjit5190 Mar 16 at 8:27
  • That is perfect! Thank you so much! – jarod Mar 16 at 11:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.