Cited from Trailhead module.

Use the Wire Service to Get Data for presentation (Read Only)

We call the wire service reactive in part because it supports reactive variables, which are prefixed with $. If a reactive variable changes, the wire service provisions new data. We say “provisions” instead of “requests” or “fetches” because the wire adapter, not the component, controls when data is provided.

import { LightningElement, api, track, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Property__c.Name';
import PICTURE_FIELD from '@salesforce/schema/Property__c.Picture__c';
export default class PropertySummary extends LightningElement {
    @api recordId;
    @track propertyName;
    @track pictureURL;
    @wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD, PICTURE_FIELD] })
    wiredRecord({ error, data }) {
        if (data) {
            this.propertyName = getFieldValue(data, NAME_FIELD);
            this.pictureURL = getFieldValue(data, PICTURE_FIELD);
        } else if (error) {
            // Handle error. Details in error.message.

Because $recordId is prepended with a $, when its value changes, the wire service gets new data and provisions it to the component. When new data is provided, the wired function gets invoked. That process updates the @track properties, which in turn cause a rerender.
The wiredRecord function receives the stream of data from the wire service. The record data is returned to the data argument. Any error is returned to the error argument.

Don’t use @wire to create, update, or delete a record. The wire service delegates control flow to the Lightning Web Components engine. Delegating control is great for read operations, but it isn’t great for create, update, and delete operations. As a developer, you want complete control over operations that change data. That’s why you perform create, update, and delete operations with a JavaScript API instead of with the wire service.

Use JavaScript API Methods to Write Data

import { LightningElement, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { createRecord } from 'lightning/uiRecordApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
export default class LdsCreateRecord extends LightningElement {
    @track accountId;
    onNameChange(event) { =;
    createAccount() {
        const recordInput = {
            apiName: ACCOUNT_OBJECT.objectApiName
            fields: { 
            .then(account => {
                this.accountId =;
                    new ShowToastEvent({
                        title: 'Success',
                        message: 'Account created',
                        variant: 'success',
            .catch(error => {
                // Handle error. Details in error.message.


    <lightning-card title="LdsCreateRecord" icon-name="standard:record">
        <div class="slds-m-around_medium">
            <lightning-input label="Id" disabled value={accountId}></lightning-input>
            <lightning-input label="Name" onchange={onNameChange} class="slds-m-bottom_x-small"></lightning-input>
            <lightning-button label="Create Account" variant="brand" onclick={createAccount}></lightning-button>

Use Apex for Custom Data Access, wire Service to Call an Apex Method

If an Apex method is cacheable (it doesn’t mutate data), you can invoke it from a component via the wire service. You must annotate the method with @AuraEnabled(cacheable=true).

Don’t @wire an Apex method that creates, updates, or deletes data.

// MyAccountController.cls
public with sharing class MyAccountController {
    public static List<Account> getAccounts() {
        return [SELECT Id, Name FROM Account
            WHERE AnnualRevenue > 1000000];


import { LightningElement, track, wire } from 'lwc';
import getAccounts from '@salesforce/apex/MyAccountController.getAccounts';
export default class HelloApexAccounts extends LightningElement {
    @track accounts=[];
    @wire(getAccounts, {})
    wiredAccounts({ error, data }) {
        if (error) {
            this.error = error;
        } else if (data) {
            this.accounts = data;

Call an Apex Method Directly

If an Apex method mutates (creates, updates, or deletes) data and therefore isn’t cacheable, you must call the method directly in code.

import { LightningElement, track } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';
export default class ApexContactList extends LightningElement {
    @track contacts;
    getContacts() {
            .then(result => {
                this.contacts = result;
            .catch(error => {
                // Handle error. Details in error.message.