Skip to main content

Usar o Apex para trabalhar com dados

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:

  • Reconhecer quando você precisa usar o Apex para trabalhar com os dados do Salesforce.
  • Chamar o Apex de duas maneiras diferentes.
  • Trabalhar com listas de registros usando o Apex e lightning-datatable.
Nota

Nota

Deseja aprender em português (Brasil)? Nesse emblema, as validações dos desafios práticos do Trailhead funcionam em inglês. As traduções são fornecidas entre parênteses como referência No Trailhead Playground, (1) mude a localidade para Estados Unidos, (2) mude o idioma para inglês e (3) copie e cole apenas os valores em inglês. Siga as instruções aqui.

Consulte o emblema Trailhead no seu idioma para saber mais sobre como aproveitar a experiência de Trailhead em outros idiomas.

Apex em componentes Web do Lightning

Já abordamos os benefícios do Lightning Data Service e como usá-lo, mas, às vezes, nem os componentes do lightning-record-*-form nem os adaptadores de conexão e as funções do LDS se adequam a um caso de uso específico. Por exemplo, quando você deseja personalizar uma transação com dados de registro único ou realizar operações com vários registros em uma única transação, o Apex é a melhor opção.

Usar métodos do Apex com componentes Web do Lightning

Um método do Apex usado em um componente Web do Lightning deve ser static, public ou global e anotado com @AuraEnabled imediatamente antes da definição do método. A anotação @AuraEnabled disponibiliza o método do Apex para componentes do Lightning (tanto componentes Web do Lightning quanto componentes do Aura).

Permitir que a estrutura armazene dados em cache elimina chamadas de servidor repetidas, fazendo com que as operações de leitura futuras executem mais rapidamente. Marcamos um método como armazenável em cache definindo cacheable = true na anotação @AuraEnabled. Quando um método de @AuraEnabled pode ser armazenado em cache, as operações de linguagem de manipulação de dados (DML) não são permitidas. Na linha 2 deste exemplo, transformamos o método getContactsBornAfter em armazenável em cache.

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
       ];
    }
}

Quando um método é armazenável em cache, versões recentemente adicionadas ou alteradas de registros não podem ser retornadas até que o cache seja atualizado. Saiba como atualizar o cache manualmente na próxima seção.

Chamar métodos do Apex a partir do LWC

Existem duas maneiras de interagir com os métodos do Apex a partir de componentes Web do Lightning: conectar o método ou chamar o método imperativamente. Vamos considerar as duas abordagens.

Chamar Apex usando @wire

Para conectar um método do Apex, o método deve ser armazenável em cache. Para conectar um método do Apex armazenável em cache, use o decorador @wire (da mesma forma que você usa um adaptador de conexão do LDS). Chamar o Apex dessa forma delega o controle para o mecanismo dos componentes Web do Lightning e cria um serviço reativo. Toda vez que o valor de um parâmetro passado para o método do Apex muda, o método Apex é executado, provisionando a propriedade ou função decorada com o novo valor. Como os métodos conectados precisam ser armazenáveis em cache, os dados podem vir do cache do LDS ou do servidor. Para atualizar os dados que foram armazenados em cache por um método do Apex, chame a função refreshApex.

Nota: o Lightning Data Service não tem conhecimento dos dados armazenados em cache por métodos do Apex. Quando uma função do LDS atualiza um registro, essa atualização não afeta os dados que foram armazenados em cache por um método do Apex.

Veja um exemplo de como usar @wire para chamar o Apex. Este código obtém contatos que nasceram após a data de nascimento 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;
}

Destaques do código:

  • Linha 2: importamos a função getContactsBornAfter da classe do Apex ContactController. Isso aponta para o método do Apex correspondente.
  • Linha 4: Definimos uma propriedade @api minBirthDate. Quando você usa este componente em seu código ou expõe um atributo FlexiPage, você pode passar uma data para a propriedade @api minBirthDate.
  • Linha 5: O decorador @wire recebe dois parâmetros: o método do Apex que queremos chamar (getContactsBornAfter) e o parâmetro de que o adaptador precisa (birthDate). Passamos $minBirthDate como uma variável reativa (começando com $).
  • Linha 6: o resultado é armazenado na propriedade contacts.
  • Linhas 5 a 6: inicialmente, o método do Apex provisiona dados à propriedade contacts e armazena esses dados no cache do LDS. Como $minBirthDate é reativa, cada vez que seu valor muda, o método do Apex provisiona novos dados, seja a partir do cache ou do servidor.

Chamar Apex imperativamente

Uma alternativa a chamar o Apex com @wire é chamar imperativamente o Apex. Chame o Apex imperativamente quando precisar controlar a invocação de operações de leitura e quando modificar registros. Para chamar o Apex de forma imperativa, invoque a função importada do arquivo JavaScript do componente. A função retorna uma promessa de JavaScript (como acontece quando você chama uma função do LDS imperativamente).

Você pode chamar tanto os métodos do Apex que podem ser armazenados em cache quanto os que não podem imperativamente. No entanto, você não pode atualizar um método do Apex armazenado em cache imperativamente. Em vez disso, chame o método usando @wire e atualize-o com refreshApex.

No exemplo callApexImperative.js, quando um usuário clica em um lightning-button no arquivo .html (não mostrado), handleButtonClick chama o método do Apex getContactsBornAfter imperativamente.

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
            });
    }
}

Destaques do código:

  • Linha 2: importamos a função getContactsBornAfter da classe ContactController.
  • Linha 4: Definimos uma propriedade pública minBirthDate para a qual você pode passar uma data ao usar este componente em seu código ou expor um atributo FlexiPage.
  • Linhas 6 a 7: Quando o método handleButtonClick é invocado pela estrutura, invocamos o método do Apex getContactsBornAfter imperativamente, passando a birthDate de que o método precisa para obter os contatos relacionados à data de nascimento especificada.
  • Linhas 9 a 14: a chamada do Apex imperativa na linha 6 retornou uma promessa. Se a chamada do método do Apex for bem-sucedida, a promessa será cumprida e o método then será executado. Caso contrário, a promessa será rejeitada e o método catch será executado.

A maneira preferencial de trabalhar com listas de registros nos componentes Web do Lightning é usar o componente base lightning-datatable. Use lightning-datatable para criar tabelas de dados com recursos como rolagem infinita, edição inline, cabeçalho e ações no nível da linha, redimensionamento e muito mais. Esse componente de IU precisa ser alimentado com dados. A maneira mais comum de gerar esses dados é chamar o Apex em qualquer uma das maneiras explicadas anteriormente neste módulo.

Implantar um componente Web do Lightning que lista registros em uma tabela

Vamos trabalhar com um exemplo que exibe uma lista de contas existentes em lightning-datatable. Usaremos o Apex e @wire para recuperar os registros.

  1. Crie uma classe do Apex chamada AccountController:
    1. No painel do Explorer, clique com o botão direito na pasta classes e selecione SFDX: Criar classe do Apex.
    2. No nome da classe, insira AccountController e pressione Enter.
    3. Pressione Enter novamente para aceitar o diretório padrão.
  2. Substitua o conteúdo da classe AccountController por 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
            ];
        }
    }
    Destaques do código:
    • Linha 2: anotamos o método com @AuraEnabled(cacheable=true) para que os resultados sejam armazenados em cache.
    • Linha 3: definimos o método getAccounts no Apex para realizar uma operação de leitura e recuperar contas existentes.
  3. Crie um componente Web do Lightning chamado accountList.
  4. Substitua o conteúdo de seu accountList.js por este 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;
    }

    Destaques do código:
    • Linhas 2 a 4: importamos referências de campo, como nos exemplos anteriores.
    • Linha 5: importamos a função getAccounts da classe AccountController.
    • Linha 13: usamos @wire com a função getAccounts para recuperar os dados.
    • Linha 14: armazenamos o resultado na propriedade accounts. Se a operação for bem-sucedida, os registros podem ser acessados em accounts.data. Se não for, o erro aparecerá em accounts.error.
  5. Substitua o conteúdo de seu arquivo accountsList.html por este 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>
    Destaques do código:
    • Linhas 4 a 9: definimos o componente básico lightning-datatable para usar accounts.data e columns que são preenchidos no arquivo JavaScript.
  6. Salve sua classe AccountController.
  7. Substitua o conteúdo de seu accountList.js-meta.xml por este código para que o componente esteja disponível nas páginas do aplicativo:
    <?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>
  8. Salve todos os três arquivos de componente.
  9. Implante a pasta force-app/main/default em seu Trailhead Playground.
  10. Em seu Trailhead Playground, navegue até o Criador de aplicativo Lightning e abra a página Working with Data (Como trabalhar com dados).
  11. Arraste o componente accountList até a região principal da página.
  12. Salve a página.
  13. Volte para a página Working with Data (Como trabalhar com dados) para ver seu novo componente.
Nota

Algumas coisas a serem consideradas ao usar o componente lightning-datatable.

  • Alguns tipos de dados atualmente não são compatíveis com o componente lightning-datatable. No entanto, você pode usar tipos personalizados. Para saber mais, role a tela para acessar Criar tipos de dados personalizados na documentação.
  • O componente lightning-datatable atualmente não funciona em dispositivos móveis. Se você precisar de compatibilidade com dispositivos móveis, crie uma tabela personalizada.

Agora você sabe algumas maneiras de interagir com os dados do Salesforce em seus componentes Web do Lightning. Em seguida, você aprenderá a lidar com erros do servidor quando eles ocorrerem.

Recursos

Continue a aprender de graça!
Inscreva-se em uma conta para continuar.
O que você ganha com isso?
  • Receba recomendações personalizadas para suas metas de carreira
  • Pratique suas habilidades com desafios práticos e testes
  • Monitore e compartilhe seu progresso com os empregadores
  • Conecte-se a orientação e oportunidades de carreira