Manage Attribute Dependencies in a Getter
An attribute in HTML turns into a property assignment in JavaScript. In both cases, the order of assignment is not guaranteed. To check for the existence of other attributes, use a getter.
Use a getter reference in the template. Don’t use the @api getter, and don’t use an @api setter that relies on a value from another @api property.
Let’s assume we have a datatable component that displays a check mark on selected rows. We have two separate attributes rows and selectedRows, which have a dependency on the other.
1<template>
2 <c-datatable selected-rows="1,2" rows="1,2,3,4"> </c-datatable>
3</template>
Since the order in which the attributes are received isn’t guaranteed, use getters to check the dependency.
1export default class Datatable extends LightningElement {
2 @track state = {};
3
4 @api
5 get rows() {
6 return this.state.rows;
7 }
8
9 set rows(value) {
10 this.state.rows = value;
11
12 // Check to see if the rows have
13 // been marked as selected.
14 if (this.state.selectedRows && !this.selectedRowsSet) {
15 this.markSelectedRows();
16 this.selectedRowsSet = true;
17 }
18 }
19
20 @api
21 set selectedRows(value) {
22 this.state.selectedRows = value;
23
24 // If rows haven’t been set,
25 // then we can't mark anything
26 // as selected.
27 if (!this.state.rows) {
28 this.selectedRowsSet = false;
29 return;
30 }
31
32 this.markSelectedRows();
33 }
34
35 get selectedRows() {
36 return this.state.selectedRows;
37 }
38
39 markSelectedRows() {
40 // Mark selected rows.
41 }
42}
Using getters and setters ensures that the public API contract is easily enforced. A component shouldn’t change the value of a property that’s annotated with @api.
Normalize data in the setter if something depends on that value at set time, for example, to append a CSS class programmatically on an element. Return the original value in the getter. Normalization can also be done in the getter so that the template has access to a value even if the consumer doesn’t set anything.
1@track state = {
2 selected : false
3};
4
5privateSelected = 'false';
6
7@api
8get selected() {
9 return this.privateSelected;
10}
11set selected(value) {
12 this.privateSelected = value;
13 this.state.selected = normalizeBoolean(value)
14}