Current week is Lightning Web Components (LWC) week. So I tried my hands on it and created a sample app. Using this sample app you will get the idea of Lightning Web Component (LWC) Datatable, LWC Lightning Data Service ( LDS ) RecordEditForm components. We will also check how to pass data between components using events and how to call apex method from Lightning Web Components (LWC).

But if you are still not sure how to setup the LWC environment then you can check my previous post. Here I have shared the step by step guide to setup VS code and create your first Lightning Web Components.
After we complete this modules this is how our final output will look like.



First we will check the Lightning Datatable component
lwcDataTable.html
<template>
<div style="height: 300px;">
<lightning-datatable
key-field="id"
data={data}
columns={columns}
onrowselection={getSelectedName}
>
</lightning-datatable>
</div>
</template>
lwcDataTable.js
import { LightningElement, wire, api, track } from 'lwc';
import initRecords from '@salesforce/apex/LWCDataTableController.initRecords';
export default class LwcDataTable extends LightningElement {
@api objectApiName = 'Contact';
@track data;
@track columns;
@wire(initRecords, { ObjectName: '$objectApiName', fieldNamesStr: 'Name,Title,Email,Phone', Orderby: 'Id', OrderDir: 'ASC' })
wiredContacts({data}) {
if (data) {
this.data = data.sobList;
this.columns = data.ldwList;
}
}
getSelectedName(event) {
const selectedRows = event.detail.selectedRows;
if(selectedRows.length > 0) {
const selectedEvent = new CustomEvent('selected', { detail: selectedRows[0].Id });
// Dispatches the event.
this.dispatchEvent(selectedEvent);
}
}
}
So first we will check what does this code contains
A decorator is:
- an expression
- that evaluates to a function
- that takes the target, name, and decorator descriptor as arguments
- and optionally returns a decorator descriptor to install on the target object
In our current component we are using two decorator. A property can have only one decorator.
@api: To expose a public property we decorate it with @api. An owner component that uses the component in its markup can access the component’s public properties. Public properties are reactive means if there is any value change detected then component rerender.
@react: To track a private property’s value and rerender a component when it changes, decorate the property with @track
. Tracked properties are private, where properties decorated with @api are public and can be set by another component.
Naming Conventions: In LWC we strictly need to follow naming conventions. They are
- Must begin with a letter
- Must contain only alphanumeric or underscore characters
- Must be unique in the namespace
- Can’t include whitespace
- Can’t end with an underscore
- Can’t contain two consecutive underscores
- Can’t contain a hyphen (dash)
Also It would be better if you use camelCase format. So that when you refer your component you can do <c-camel-case/>. Also remember to start the component name from lowercase. Else you will face error or you need to use –.
import { LightningElement, wire, api, track } from ‘lwc’;
We need to first import them into our component. We use above syntax to import them.
Call Apex Method:
To call apex method we can use wire approach. First we import the wire.
import initRecords from ‘@salesforce/apex/LWCDataTableController.initRecords’;
the syntax is import method name @salesforce/apex/namespace.ClassName.MethodName
and then we need to call it. We can pass multiple parameters. In response we get a object which we can use in our code and in html file as well.
@wire(initRecords, { Param1: ‘Value1’, Param2: ‘Value2’})
wiredContacts({data}) {
if (data) {
}
}
When any event occur we call the method then using event parameter we can get the details. Like in above datatable when we check the checkbox we get the selected rows using event.
Communicate Between components /Pass data between components:
Similar with Lightning Components in Lightning web components also we use Events to pass data between component. First we need to create the event and then we dispatch the Event.
` const selectedEvent = new CustomEvent(‘selected’, { detail: selectedRows[0].Id });
// Dispatches the event.
this.dispatchEvent(selectedEvent);`
Here we created a selected component and pass the first selected row record Id in another component. A parent component which is referring this child component can read this event using the onselected attribute. We will see this in parent LightningDataService component.
lwcLightningDataService.html
<template>
<c-lwc-data-table onselected={contactSelected}></c-lwc-data-table>
<template if:true={showLDS}>
<lightning-card title="Record Edit Form Contact" icon-name="standard:contact">
<div class="slds-m-around_medium">
<lightning-record-edit-form
object-api-name={objectApiName}
record-id={recordId} onsuccess={handleSuccess}>
<lightning-messages></lightning-messages>
<lightning-input-field field-name="Name"></lightning-input-field>
<lightning-input-field field-name="Title"></lightning-input-field>
<lightning-input-field field-name="Phone"></lightning-input-field>
<lightning-input-field field-name="Email"></lightning-input-field>
<div class="slds-m-top_medium">
<lightning-button variant="brand" type="submit" name="save" label="Save"></lightning-button>
</div>
</lightning-record-edit-form>
</div>
</lightning-card>
</template>
</template>
Here you will notice two things. First as explained earlier we are using onselected to catch the event. Second even we didn’t given any spaces still we are using c-lwc-data-table
syntax because we have used camelCase naming format.
import { LightningElement, api, track } from 'lwc';
export default class LwcLightningDataService extends LightningElement {
@track recordId;
@track showLDS = false;
@api objectApiName = 'Contact';
contactSelected(event) {
const contactId = event.detail;
this.recordId = contactId;
this.showLDS = true;
}
handleSuccess(event) {
// event.detail.id;
alert('Record updated successfully.');
}
}
so here many things are same with our earlier component. Also we used class and extends, export keywords here. These all are part of Lightning Web Component standards. So now if we need to find any related stuff then we can refer them globally because they all will be same in any language which is following new standards.
So now we get the good idea of how basic flow works in Lightning Web Components and you can try your hands on it. Here most of the things are dynamic so you can easily change and try this code with other supported objects as well.
You can find the complete code reference here.
Do you want to add anything here, let me know in comments. Happy programming :).
Great site! My team and I have been starting to code with LWC. One of the challenges we’ve had with datatables is not being able to use a column alias with modified data from our apex controller.
Previously used to do something like this:
for (let i = 0; i < data.length; i++) {
let row = data[i];
row.columnAlias = row.ObjectName__r.Name;
}
This is very common because you need to do it with Aura to get data from related objects. Have you found an equivalent in LWC yet? After a bunch of testing… we're stuck!
I am able to get the value but when I update in data I am getting exception too. Look like it is related to LWC side. You can post in SFSE might get some help. You can share the post for code
Thanks Tushar, I’ll circle back when we determine how to do it.