← Back to notes

Developers · Pattern

Connect Salesforce to Salesforce using JWT

How to design an editable Salesforce table that is driven by Apex metadata instead of hardcoded columns.

Connect Salesforce to Salesforce using JWT

When a Salesforce table starts as a simple screen, hardcoding columns feels natural. But as soon as the same component needs to support different record types, picklists, editable fields and business-specific layouts, the HTML becomes fragile.

The pattern I prefer is to split the problem into two payloads: data and metadata. Records tell the component what values exist. Metadata tells it how each value should be rendered.

The problem

A table that renders Transaction__c records may need to show dates, currency values, lookup references, record type selectors and dependent picklists. If every field is represented by custom markup, every business change becomes a code change.

Goal: build the table once, then let Apex describe which fields exist, how they behave and which picklist values are valid for the selected record type.

Suggested payload shape

{
  records: [
    { Id: 'a01...', Amount__c: 1200, Motivo__c: 'REVIEW' }
  ],
  fields: [
    {
      apiName: 'Motivo__c',
      label: 'Motivo',
      dataType: 'Picklist',
      editable: true,
      picklistName: 'Motivo__c'
    }
  ],
  picklistsByRecordType: {
    '012...': {
      'Motivo__c': [
        { label: 'Review', value: 'REVIEW' }
      ]
    }
  }
}

Apex responsibilities

  • Query the records that the screen needs.
  • Describe the object and relevant fields.
  • Return field labels, API names, data types and editability flags.
  • Resolve picklist values by record type when the UI cannot safely infer them.

LWC responsibilities

  • Iterate over fields to create the table header.
  • For each row, use the current field metadata to decide which cell renderer to use.
  • Keep draft values separate from original record values.
  • Use the record type ID to select the correct picklist options.
getCellContext(row, field) {
  return {
    value: row[field.apiName],
    isPicklist: field.dataType === 'Picklist',
    isDate: field.dataType === 'Date' || field.dataType === 'DateTime',
    options: this.getPicklistOptions(row.RecordTypeId, field.apiName)
  };
}

Trade-offs

This design adds upfront structure. It is not worth it for a tiny one-off table. It becomes valuable when the UI must survive layout changes, multiple record types, evolving picklists or reuse across objects.

When I would use this

  • Operational screens with many fields and frequent business changes.
  • Components that must support more than one record type.
  • Internal tools where admins request new columns often.

When I would not use this

  • Very small forms with two or three stable fields.
  • Highly custom interactions where every cell has unique behavior.