8

In the salesforce trailhead "Lightning Web Components and Salesforce Data: Use Apex to Work with Data" we have the following code:

import { LightningElement, wire } from "lwc";
import NAME_FIELD from "@salesforce/schema/Account.Name";
import REVENUE_FIELD from "@salesforce/schema/Account.AnnualRevenue";
import INDUSTRY_FIELD from "@salesforce/schema/Account.Industry";
import getAccounts from "@salesforce/apex/AccountController.getAccounts";
const COLUMNS = [
  { label: "Account Name", fieldName: NAME_FIELD.fieldApiName, type: "text" },
  {
    label: "Annual Revenue",
    fieldName: REVENUE_FIELD.fieldApiName,
    type: "currency"
  },
  { label: "Industry", fieldName: INDUSTRY_FIELD.fieldApiName, type: "text" }
];
export default class AccountList extends LightningElement {
  columns = COLUMNS;
  @wire(getAccounts)
  accounts;
}

In this example, and in many others, variables such as COLUMNS are established outside of the central class, rather than inside of it. This is then followed up by something line the line columns = COLUMNS.

Why is this? Is there a technical reason for it? Is it just a syntax standard? Why isn't the code written more like this:

import { LightningElement, wire } from "lwc";
import NAME_FIELD from "@salesforce/schema/Account.Name";
import REVENUE_FIELD from "@salesforce/schema/Account.AnnualRevenue";
import INDUSTRY_FIELD from "@salesforce/schema/Account.Industry";
import getAccounts from "@salesforce/apex/AccountController.getAccounts";

export default class AccountList extends LightningElement {
  columns = [
     { label: "Account Name", fieldName: NAME_FIELD.fieldApiName, type: "text" },
     { label: "Annual Revenue",fieldName: REVENUE_FIELD.fieldApiName,type: "currency" },
     { label: "Industry", fieldName: INDUSTRY_FIELD.fieldApiName, type: "text" }
  ];
  @wire(getAccounts)
  accounts;
}
1
  • I've often wondered this myself. Does it confer a speed benefit? A binding benefit? (To the attached template). Readability? or is it just new, so we all gotta do it. Commented Mar 16, 2021 at 1:17

1 Answer 1

11

The general "rule" is that you put global constants (const) outside the class, which is reminiscent of how constants were used in the old days (e.g. the C language). You cannot place a const inside a class and outside of any function. The following is illegal:

export default class MyClass extends LightningComponent {
  const name = value;
}

However, defining a constant outside the class is beneficial, as it reduces the size of your class and makes it easier to read.

In general, your class should look like this:

import things from 'places';

const thatAreGlobal;

export default class MyClass extends LightningElement {
  // public properties
  @api variables;
  // public methods
  @api methods;

  // private properties, also @track'ed variables
  classVariables;

  // Wire methods
  @wire(method, params) result;
  
  // First code to run
  constructor() { // if any
  }
  
  handlers() { // if any
    const somevariable = this.someothermethod(); // we can do this, though.
  }

  utilityAndHelpers() { // if any
  }
}

This is meant to keep your code organized, similar to how you should structure a Java class, Apex class, C++ file, etc. Keeping things grouped together makes it easier to maintain in the long run, rather than just randomly putting variables, etc, everywhere.

5
  • I'm not entirely convinced I like this design pattern, despite it being the correct answer. I don't think it works well with web components, as generally you have just one class + one template + one css file. So what does 'global' actually mean in that context? Commented Mar 16, 2021 at 3:24
  • 1
    @CasparHarmer "global" is more historical nomenclature, but in modern JS means "anywhere in the file." I agree that for small scripts, the const design is unnecessary, but I find it helpful once you start building larger classes that are thousands of lines long; there comes a point where organization is more beneficial than "shorter." My main argument is to avoid magic numbers, but also to allow easier configuration changes to your source (e.g. columns to display).
    – sfdcfox
    Commented Mar 16, 2021 at 3:51
  • 1
    @CasparHarmer Mind you, I'm not saying, one must absolutely do it this way or face the wrath of some nameless programming deity, but I do speak from 33+ years of experience in a couple dozen different languages. Putting your configuration in its own special, immutable place in the file is an awesome feature to have when you're building large scripts.
    – sfdcfox
    Commented Mar 16, 2021 at 3:54
  • 3
    @sfdcfox Here is another reason for moving immutable objects outside the class body. In JavaScript class fields with initial value is a shortcut for creating a property in the constructor and assigning value. This avoids duplicate allocation of the same immutable object: jsfiddle.net/haLf16km/1
    – pmdartus
    Commented Mar 22, 2021 at 9:45
  • @pmdartus That's an excellent point. Using inline values in a loop of components would balloon memory usage unnecessarily.
    – sfdcfox
    Commented Mar 22, 2021 at 11:25

You must log in to answer this question.

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