Skip to main content

Utilizar Apex para trabajar con datos

Objetivos de aprendizaje

Después de completar esta unidad, podrá:

  • Reconocer cuándo necesita utilizar Apex para trabajar con datos de Salesforce.
  • Llamar Apex de dos formas diferentes.
  • Trabajar con listas de registros utilizando Apex y lightning-datatable.
Nota

Nota

¿Es su idioma de aprendizaje español (LATAM)? Comience el reto en un Trailhead Playground en español (LATAM) y utilice las traducciones entre paréntesis para navegar. Copie y pegue solo los valores en inglés, ya que las validaciones del reto dependen de los datos en ese idioma. Si no aprueba el reto en su organización en español (LATAM), recomendamos que (1) cambie la configuración local a Estados Unidos, (2) cambie el idioma a inglés (según estas instrucciones) y, luego, (3) haga clic en el botón “Check Challenge” (Comprobar el reto) nuevamente.

Consulte la insignia Trailhead en su idioma para obtener más información sobre cómo aprovechar la experiencia de Trailhead en otros idiomas.

Apex en componentes web Lightning

Tratamos las ventajas de Lightning Data Service y cómo utilizarlo, pero a veces, ni los componentes lightning-record-*-form ni las funciones y los adaptadores de red de LDS responden a un caso de uso concreto. Por ejemplo, cuando desea personalizar una transacción de datos de un solo registro, o realizar operaciones de múltiples registros en una sola transacción, Apex es la mejor opción.

Utilizar métodos de Apex con componentes web Lightning

Un método de Apex utilizado en un componente web Lightning debe ser static, public o global, y anotado con @AuraEnabled inmediatamente antes de la definición del método. La anotación @AuraEnabled hace que el método de Apex esté disponible en componentes Lightning (tanto componentes web Lightning como componentes Aura).

Permitir al marco de trabajo almacenar datos en caché elimina las llamadas del servidor repetidas haciendo que las operaciones de lectura futuras se ejecuten de forma más rápida. Marcamos un método como con capacidad de caché estableciendo cacheable = true en la anotación @AuraEnabled. Cuando un método @AuraEnabled tiene capacidad de caché, no se permiten operaciones de Lenguaje de manipulación de datos (DML). En la línea 2 de este ejemplo, hacemos que el método getContactsBornAfter tenga capacidad de caché.

ContactController.cls

public with sharing class ContactController {
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContactsBornAfter(Date birthDate) {
        return [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE Birthdate > :birthDate
            WITH SECURITY_ENFORCED
       ];
    }
}

Cuando un método tiene capacidad de caché, las versiones recién agregadas o modificadas de registros podrían no ser devueltas hasta que se actualice el caché. Obtenga información acerca de cómo actualizar manualmente el caché en la siguiente sección.

Llamar métodos de Apex desde LWC

Existen dos formas de interactuar con métodos de Apex desde componentes web Lightning: conectar el método o llamar al método de forma imperativa. Consideremos ambos enfoques.

Llamar a Apex utilizando @wire

Para conectar un método de Apex, el método debe tener capacidad de caché. Para conectar un método de Apex con capacidad de caché, utilice el decorator @wire (del mismo modo que utiliza un adaptador de red de LDS). Llamar a Apex de este modo delega el control al motor Componentes web Lightning y crea un servicio reactivo. Cada vez que cambia el valor de un parámetro que pasó al método de Apex, se ejecuta el método de Apex y se proporciona el nuevo valor a la función o propiedad decoradas. Como los métodos conectados deben tener capacidad de caché, los datos pueden proceder del caché de LDS o el servidor. Para actualizar los datos que se almacenaron en caché por un método de Apex, llame la función refreshApex.

Nota: Lightning Data Service no está al tanto de los datos almacenados en caché por métodos de Apex. Cuando una función de LDS actualiza un registro, esa actualización no tiene ninguna repercusión en datos almacenados en caché por un método de Apex.

Este es un ejemplo del uso de @wire para llamar a Apex. Este código obtiene contactos que nacieron después de la fecha de nacimiento especificada.

wireApexProperty.js

import { LightningElement, api, wire } from 'lwc';
import getContactsBornAfter from '@salesforce/apex/ContactController.getContactsBornAfter';
export default class WireApexProperty extends LightningElement {
    @api minBirthDate;
    @wire(getContactsBornAfter, { birthDate: '$minBirthDate' })
    contacts;
}

Aspectos destacados de código:

  • Línea 2: importamos la función getContactsBornAfter desde la clase de Apex ContactController. Esto apunta al método de Apex correspondiente.
  • Línea 4: definimos una propiedad @api minBirthDate. Cuando usa este componente en su código o expone un atributo FlexiPage, puede pasar una fecha a la propiedad @api minBirthDate.
  • Línea 5: el decorador @wire recibe dos parámetros: el Método Apex al que queremos llamar (getContactsBornAfter) y el parámetro que el adaptador necesita (birthDate). Pasamos $minBirthDate como una variable reactiva (comenzando por $).
  • Línea 6: el resultado se almacena en la propiedad contacts (contactos).
  • Línea 5 a 6: inicialmente, el Método Apex proporciona datos a la propiedad contacts (contactos) y almacena esos datos en la caché de LDS. Como $minBirthDate es reactivo, cada vez que su valor cambia, el Método Apex ejecuta y proporciona nuevos datos, ya sea de la caché o del servidor.

Llamar Apex de forma imperativa

Una alternativa a llamar a Apex con @wire es llamar a Apex de forma imperativa. Llame a Apex de forma imperativa cuando necesite controlar la invocación de operaciones de lectura y cuando modifique registros. Para llamar a Apex de forma imperativa, invoque la función importada desde el archivo JavaScript del componente. La función devuelve un compromiso de JavaScript (como cuando llama a una función de LDS de forma imperativa).

Puede llamar métodos de Apex tanto con capacidad de caché como sin capacidad de caché de forma imperativa. Sin embargo, no puede actualizar un método de Apex con capacidad de caché de forma imperativa. En su lugar, llame al método @wire y actualícelo con refreshApex.

En el ejemplo callApexImperative.js, cuando un usuario hace clic en un lightning-button en el archivo .html (no mostrado), handleButtonClick llama al método de Apex getContactsBornAfter de forma imperativa.

callApexImperative.js

import { LightningElement, api, wire } from 'lwc';
import getContactsBornAfter from '@salesforce/apex/ContactController.getContactsBornAfter';
export default class CallApexImperative extends LightningElement {
    @api minBirthDate;
    handleButtonClick() {
        getContactsBornAfter({ //imperative Apex call
            birthDate: this.minBirthDate
        })
            .then(contacts => {
                //code to execute if related contacts are returned successfully
            })
            .catch(error => {
                //code to execute if related contacts are not returned successfully
            });
    }
}

Aspectos destacados de código:

  • Línea 2: importamos la función getContactsBornAfter desde la clase ContactController.
  • Línea 4: definimos una propiedad minBirthDate pública, a la que puede pasar una fecha mediante este componente en su código o si expone un atributo FlexiPage.
  • Línea 6 a 7: cuando el marco de trabajo invoca el método handleButtonClick, invocamos el Método Apex getContactsBornAfter de forma imperativa y pasamos el parámetro birthDate que el método necesita para obtener los contactos nacidos después de la fecha de nacimiento especificada.
  • Línea 9 a 14: La llamada de Apex imperativa en la línea 6 devolvió un compromiso. Si la llamada del Método Apex se realiza correctamente, el compromiso se cumple y se ejecuta el método then. De lo contrario, el compromiso se rechaza y se ejecuta el método catch.

La forma preferida de trabajar con listas de registros en componentes web Lightning es utilizar el componente base  lightning-datatable. Utilice lightning-datatable para crear tablas de datos con funciones como desplazamiento infinito, modificación en línea, acciones a nivel de fila y encabezado, ajuste de tamaño y mucho más. Este componente de la interfaz de usuario debe ser datos de federación. La forma más común de generar esos datos es llamar a Apex en cualquiera de las formas explicadas anteriormente en este módulo.

Implementar un componente web Lightning que enumera registros en una tabla

Trabajemos con un ejemplo que muestra una lista de cuentas existentes en lightning-datatable. Utilizaremos Apex y @wire para recuperar los registros.

  1. Cree una clase de Apex denominada AccountController:
    1. En el panel Explorador, haga clic con el botón derecho en la carpeta clases y seleccione SFDX: Crear clase de Apex.
    2. Para el nombre de clase, ingrese AccountController y pulse Enter (Intro).
    3. Pulse Entrar de nuevo para aceptar el directorio predeterminado.
  1. Sustituya los contenidos de su clase AccountController con este código:
    public with sharing class AccountController {
        @AuraEnabled(cacheable=true)
        public static List<Account> getAccounts() {
            return [
                SELECT Name, AnnualRevenue, Industry
                FROM Account
                WITH SECURITY_ENFORCED
                ORDER BY Name
            ];
        }
    }
    Aspectos destacados de código:
    • Línea 2: anotamos el método con @AuraEnabled(cacheable=true) de modo que se almacenen los resultados en la caché.
    • Línea 3: definimos el método getAccounts en Apex para realizar una operación de lectura y recuperar las cuentas existentes.
  1. Cree un componente web Lightning denominado accountList.
  2. Sustituya los contenidos de su archivo accountList.js por el siguiente código:
    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;
    }
    Aspectos destacados de código:
    • Línea 2 a 4: Importamos referencias de campo, al igual que en los pasos anteriores.
    • Línea 5: importamos la función getAccounts desde la clase AccountController.
    • Línea 13: utilizamos @wire con la función getAccounts para recuperar los datos.
    • Línea 14: almacenamos el resultado en la propiedad accounts (cuentas). Si la operación se realiza correctamente, se puede acceder a los registros en accounts.data. Si falla, el error aparece en accounts.error.
  1. Sustituya los contenidos de su archivo accountList.html por el siguiente código:
    <template>
        <lightning-card>
            <template if:true={accounts.data}>
                <lightning-datatable
                    key-field="Id"
                    data={accounts.data}
                    columns={columns}
                >
               </lightning-datatable>
            </template>
        </lightning-card>
    </template>
    Aspectos destacados de código:
    • Línea 4 a 9: definimos el componente base lightning-datatable para utilizar accounts.data y columns que se rellenan en el archivo JavaScript.
  1. Guarde su clase AccountController.
  2. Sustituya los contenidos de su accountList.js-meta.xml con este código de modo que el componente esté disponible en páginas de aplicación:
    <?xml version="1.0" encoding="UTF-8"?>
    <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
        <apiVersion>48.0</apiVersion>
        <isExposed>true</isExposed>
        <targets>
            <target>lightning__AppPage</target>
        </targets>
    </LightningComponentBundle>
  3. Guarde los tres archivos de componente.
  4. Implemente la carpeta force-app/main/default en su Trailhead Playground.
  5. En su instancia de Trailhead Playground, desplácese al Generador de aplicación Lightning y abra la página Working with Data (Trabajo con los datos).
  6. Arrastre el componente accountList a la región principal de la página.
  7. Guarde la página.
  8. Vuelva a la página Working with Data (Trabajo con los datos) para ver su nuevo componente.
Nota

Algunas cosas a tener en cuenta al utilizar el componente lightning-datatable.

  • Algunos tipos de datos no son compatibles en el componente lightning-datatable en la actualidad. Sin embargo, puede utilizar tipos personalizados. Para obtener más información, desplácese a Crear tipos de datos personalizados en la documentación.
  • El componente lightning-datatable no funciona en móvil en la actualidad. Si necesita compatibilidad con móvil, cree una tabla personalizada en su lugar.

Ahora conoce algunas formas de interactuar con datos de Salesforce en sus componentes web Lightning. A continuación, obtiene información acerca de cómo gestionar errores del servidor cuando se produzcan.

Recursos

Comparta sus comentarios de Trailhead en la Ayuda de Salesforce.

Nos encantaría saber más sobre su experiencia con Trailhead. Ahora puede acceder al nuevo formulario de comentarios en cualquier momento en el sitio de Ayuda de Salesforce.

Más información Continuar a Compartir comentarios