Alura > Cursos de Front-end > Cursos de Angular > Conteúdos de Angular > Primeiras aulas do curso Angular e Supabase: refinando a aplicação com SSR

Angular e Supabase: refinando a aplicação com SSR

Desenvolvendo a lógica de compra - Apresentação

Que tal aprendermos a desenvolver um e-commerce utilizando Angular, Supabase e SSR? Me chamo Nayanne Batista e serei a sua instrutora.

Audiodescrição: Nayanne se declara uma mulher de pele morena, com olhos e cabelos castanhos escuros. Veste uma camisa laranja. Ao fundo, há uma estante grande com livros.

O que vamos aprender?

Apresentamos o projeto do e-commerce Deleite, que oferece produtos como milkshakes, sorvetes, smoothies e cafés gelados. Nosso objetivo é desenvolver a tela de checkout, onde será possível adicionar produtos ao carrinho e gerenciar as operações, como adicionar, remover e atualizar itens. Também será necessário gerenciar o estado e compartilhar este estado entre diferentes componentes.

Utilizaremos a biblioteca RxJS, com ênfase no BehaviorSubject, para auxiliar no gerenciamento de estado no Angular. A persistência de dados será realizada por meio do nosso Back-end as a Service ("Back-end como Serviço"), utilizando o banco de dados do Supabase. Também abordaremos técnicas de server side rendering (SSR), como hidratação, hidratação incremental e renderização híbrida.

Pré-requisitos

Para acompanhar este curso, é recomendável ter conhecimento intermediário sobre Angular, especialmente em relação a serviços e injeção de dependências, além de familiaridade básica com a biblioteca RxJS, sobre o funcionamento dos Observables.

Conclusão

Estamos muito animados para começar. Esperamos vocês na primeira aula para mergulharmos juntos no Angular!

Desenvolvendo a lógica de compra - Atualizando a versão do Angular no projeto

Daremos continuidade ao desenvolvimento do e-commerce Deleite utilizando SSR e SupaBase. Com o Figma aberto, temos algumas telas adicionais para criar, como a tela do carrinho e a tela "Sobre":

Tela do carrinho

Página de carrinho de compras do site 'Deleite'. No topo, há uma barra azul com o nome 'Deleite' à esquerda e opções 'Sobre' e um ícone de carrinho à direita. Abaixo, o título 'Itens do carrinho'. Lista com dois produtos: 'Milkshake de morango com baunilha', quantidade 2, totalizando R$36,00, e 'Sorvete de pistache', quantidade 1, no valor de R$12,00. A direita, área de 'Total' indicando R$48,00, com botões 'FINALIZAR O PAGAMENTO' em azul e 'CONTINUAR COMPRANDO'. No rodapé, links para redes sociais e texto informando que o site foi desenvolvido pela Alura, projeto fictício sem fins comerciais.

Tela "Sobre"

Página web fictícia da marca "Deleite", apresentando a história da empresa, com texto descritivo, imagens de produtos e baristas, além de rodapé com redes sociais e crédito ao projeto.

Atualizando a versão do Angular

Antes de prosseguir, há um aspecto importante a ser resolvido no código: quando iniciamos o projeto, o Angular estava na versão 18.

Em novembro de 2024, a versão 19 do Angular foi lançada, trazendo diversas melhorias e novos recursos, especialmente para o server side rendering. Para aproveitar essas melhorias, correções de segurança e novas funcionalidades, é essencial atualizar o projeto.

Ao falarmos sobre atualização de projeto, é comum que surjam dúvidas ou receios, como a preocupação de que o projeto, que estava funcionando corretamente, possa deixar de funcionar ou que algo possa ser comprometido. Esses questionamentos são válidos, pois as atualizações frequentemente envolvem mudanças nas dependências, novos recursos e ajustes nas APIs.

Por isso, é essencial realizar a atualização de maneira adequada e segura. Para garantir que a atualização seja realizada da melhor forma possível, o Angular oferece um guia de atualização em sua documentação.

Acessamos a documentação do Angular em angular.dev. No menu lateral esquerdo, clicamos na lupa e digitamos "update guide" no campo de busca, selecionando a primeira ocorrência. Dessa forma, encontramos um guia de atualização com um passo a passo que nos orienta a realizar a atualização da maneira mais correta possível.

No início, em "Angular versions", é necessário selecionar a versão atual do projeto e a versão para a qual ele será atualizado. No campo "From", escolhemos a versão 18, e no campo "to", escolhemos a versão 19.

Dessa forma, o projeto será atualizado da versão 18 para a 19. Abaixo, em "Application complexity" ("Complexidade da aplicação"), há um campo para selecionar a complexidade da aplicação. Dependendo da complexidade, o Angular apresentará mais ou menos etapas para ajustes. Mantemos a seleção em "Basic" ("básico").

Há um campo para selecionar outras dependências ("Other dependencies") que podem ser utilizadas no projeto:

A primeira opção refere-se ao uso do ngUpgrade, que serve para combinar o AngularJS com o Angular. Como não estamos utilizando essa ferramenta, não a marcamos.

A segunda opção é sobre o uso do Angular Material, o qual estamos utilizando, então essa opção é marcada. Também marcamos a opção referente ao Windows, pois estamos utilizando esse sistema operacional. Em seguida, clicamos em "Show me how to update", ou seja, "mostre-me como fazer essa atualização".

  1. In the application's project directory, run ng update @angular/core@19 @angular/cli@19 to update your application to Angular v19. ("No diretório do projeto da aplicação, execute ng update @angular/core@19 @angular/cli@19 para atualizar sua aplicação para o Angular v19.")
  2. Run ng update @angular/material@19.("Execute ng update @angular/material@19.")
  3. Angular directives, components and pipes are now standalone by default. Specify "standalone: false" for declarations that are currently declared in an NgModule. The Angular CLI will automatically update your code to reflect that. ("Diretivas, componentes e pipes do Angular agora são independentes por padrão. Especifique standalone: false para declarações que atualmente estão declaradas em um NgModule. O Angular CLI atualizará automaticamente seu código para refletir isso.")
  4. Replace usages of BrowserModule.withServerTransition() with injection of the APPID token to set the application id instead. ("Substitua o uso de BrowserModule.withServerTransition() pela injeção do token APP_ID para definir o id da aplicação.")
  5. Upgrade to TypeScript version 5.5 or later. ("Atualize para a versão 5.5 do TypeScript ou posterior.")
  6. Migrate from using Router.errorHandler to withNavigationErrorHandler from provideRouter or errorHandler from RouterModule.forRoot. ("Migre do uso de Router.errorHandler para withNavigationErrorHandler de provideRouter ou errorHandler de RouterModule.forRoot.")

Após o clique, será exibido um passo a passo para realizar a modificação da versão 18 para a 19. Existe uma seção de modificações necessárias antes da atualização ("Before you update"). No nosso caso, não é preciso realizar nenhuma alteração, pois não há etapas exigidas para a transição entre essas versões. Observe que há uma mensagem exibida indicando isso:

You don't need to do anything before moving between these versions

No processo de atualização em si, há um passo a passo com algumas funcionalidades que precisam ser verificadas no projeto.

O primeiro passo é executar o comando ng update para alterar a versão. Iremos copiar esse comando, abrir o terminal no projeto já carregado utilizando o atalho "Ctrl + J" e colar o comando ng update @angular/core@19 @angular/cli@19.

ng update @angular/core@19 @angular/cli@19

Após pressionarmos "Enter", o Angular iniciará a instalação da nova versão, o que pode levar alguns minutos.

O comando já baixou alguns pacotes e fez algumas modificações, pausando em uma parte de migração opcional. Há uma pergunta sobre se queremos utilizar o Application Builder, uma migração opcional que pode ser selecionada ou não com a tecla de espaço.

[use-application-builder] Migrate application projects to the new build system. (https://angular.dev/tools/cli/build-system-migration)("Migrar projetos de aplicação para o novo sistema de build. (https://angular.dev/tools/cli/build-system-migration)")

Vamos optar por fazer essa migração opcional, deixando selecionado e pressionando "Enter".

[provide-initializer] Replaces APP_INITIALIZER, ENVIRONMENT_INITIALIZER, PLATFORM_INITIALIZER respectively with provideAppInitializer, provideEnvironmentInitializer, providePlatformInitializer.("Substitui APP_INITIALIZER, ENVIRONMENT_INITIALIZER, PLATFORM_INITIALIZER respectivamente por provideAppInitializer, provideEnvironmentInitializer, providePlatformInitializer.")

Outra migração opcional apareceu em relação ao Provide de inicialização, que também deixaremos marcada e pressionaremos "Enter". A atualização foi concluída.

Verificando as alterações

Se verificarmos o que mudou no projeto, acessamos o package.json para verificar as mudanças. Estávamos na versão 18.2.10 e foi atualizada para 19.0.3, além de outras modificações. Em relação aos componentes (components.ts), algo que mudou em todos foi a flag standalone: true, que foi removida, pois agora todos os componentes são standalone por padrão. Se quisermos definir um componente como standalone: false, precisamos adicionar a propriedade.

Voltando à documentação, podemos dar um check nesse primeiro comando.

O próximo passo é atualizar o Angular Material. Para isso, copiamos o comando novamente, retornamos à aplicação e o colamos no terminal.

ng update @angular/material@19

Após teclar "Enter", recebemos uma mensagem informando que o repositório não está limpo.

Error: Repository is not clear. Please commit or stash any changes before updating

Antes de prosseguir com outras alterações, é preciso comitar as mudanças.

Commitando as alterações

Adicionamos as modificações com o comando git add ., limpamos o terminal utilizando clear para melhorar a visualização e, em seguida, realizamos o commit:

git add .
clear
git commit -m "update v19"

Após realizar o commit, repetimos o comando ng update @angular/material@19 e pressionamos "Enter". Esse comando atualizará o Angular Material. Após a atualização, retornamos à documentação e verificamos novamente. No terceiro passo, a documentação aborda a questão dos componentes standalone. Agora, diretivas, componentes e pipes são standalone por padrão.

Se estivéssemos utilizando o ngModule, essa configuração seria adicionada com o valor standalone: false. Como não utilizamos essa abordagem de módulos no projeto, simplesmente ignoramos essa parte e marcamos a verificação como concluída.

A quarta etapa não exige modificação, pois não estamos utilizando o módulo com o withServerTransition() e podemos apenas marcar essa etapa como concluída.

O próximo passo é realizar o upgrade da versão do TypeScript. Para utilizar o Angular 19, a versão do TypeScript precisa ser 5.5 ou superior. Verificamos no código, acessando o arquivo package.json. A última dependência é a do TypeScript, que já está na versão necessária, 5.5.2 ou superior. Assim, podemos retornar à documentação e marcar a verificação como concluída.

O último passo trata de uma migração na manipulação de erro do router, que também não estamos utilizando. Assim, apenas marcamos essa verificação como concluída.

Após a atualização ("After you update"), não há passos adicionais necessários. Agora, podemos retornar ao VSCode e testar se a aplicação está funcionando.

Testando a aplicação

No VSCode, digitamos o comando ng serve e pressionamos "Enter".

ng serve

A aplicação está sendo iniciada.

A aplicação iniciou, mas apareceu um aviso sobre uma importação não utilizada no app.component.ts. Vamos localizar o arquivo app.component.ts no menu lateral. Na linha 14, encontramos uma importação que não está sendo utilizada. Apagamos essa importação, assim como a da linha 5.

Linhas excluídas no arquivo app.component.ts:

// código omitido

import { HomeComponent } from './pages/home/home.component';

// código omitido

HomeComponente,

// código omitido

O erro desapareceu e agora podemos acessar o localhost clicando em "http://localhost:4200" no terminal. A aplicação está funcionando corretamente.

A tela inicial exibe os produtos e, ao clicar em um produto, somos redirecionados para a tela de detalhes. Tudo está funcionando conforme esperado. Podemos até abrir o console com "Ctrl + G" e recarregar a página clicando no ícone de seta girando na parte superior esquerda. Não há erros, tudo está em funcionamento.

Importância da atualização do projeto

É importante realizar atualizações no projeto para garantir que as dependências continuem funcionando corretamente com a nova versão do Angular. Na documentação, acima do guia de atualização à esquerda, há uma seção sobre a compatibilidade de versões ("Version compatibility"). O Angular oferece suporte ativo a algumas versões, e há uma tabela com as versões atualmente em suporte ativo.

Também existem versões que não possuem mais o LTS (Long Term Support). Isso não significa que o projeto nas versões 16, 15 ou 14 deixará de funcionar, mas sim que o Angular não está mais lançando novos recursos ou correções para essas versões. Portanto, é recomendável manter o projeto atualizado.

Próximos passos

Agora que conseguimos concluir essa etapa, daremos continuidade ao desenvolvimento da aplicação no próximo vídeo.

Desenvolvendo a lógica de compra - Desenvolvendo a tela de checkout

Vamos dar continuidade ao desenvolvimento do projeto, focando na criação da tela de checkout. Nesta tela, podemos visualizar os itens adicionados ao carrinho, incluindo a imagem, nome, valor e quantidade, que pode ser modificada. Também há um ícone de lixeira para remover itens, um card à direita com o total da compra e dois botões: um para finalizar o pagamento e outro para continuar comprando. Ao clicar no ícone de carrinho no header, seremos redirecionados para essa tela.

Antes de criar os componentes, precisamos definir as propriedades que eles terão. No menu lateral esquerdo, dentro da pasta de interfaces, já temos uma interface de produto com propriedades como ID, título, preço, imagens, ingredientes e categoria. No entanto, para os itens do carrinho, precisamos manipular também a propriedade de quantidade.

Para manter o código limpo e com responsabilidades separadas, vamos criar uma nova interface para lidar com os itens do carrinho e suas quantidades. Dentro de "interfaces", criaremos um arquivo chamado cart_item.ts:

export interface CartItem {
  product: Product; // Referência ao produto
  quantity: number; // Quantidade do produto no carrinho
}

Desenvolvimento dos componentes

Com a interface definida, vamos desenvolver os componentes. No terminal, criaremos um componente para o carrinho e um componente de página para o checkout.

ng g c component components/cart
ng g c component pages/checkout

Agora temos a pasta do componente cart com 4 arquivos e também a pasta do componente checkout com 4 arquivos.

Implementação do componente de carrinho

No arquivo cart.component.html, substituiremos o conteúdo com o HTML disponibilizado para você na atividade "Preparando o ambiente" na plataforma Alura.

Nesse HTML continuamos usando Angular Material e também a nova sintaxe de template do Angular com *@For e *@If.

E no cart.component.css vamos colar o bloco disponibilizado para o CSS.

Note que estão aparecendo alguns erros no template do HTML, porque os botões já estão com os eventos. Mas no componente ainda não estamos utilizando eles.

No cart.component.ts, faremos as importações necessárias dos módulos do Angular Material e definiremos as propriedades e métodos:

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { MatDividerModule } from '@angular/material/divider';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatOptionModule } from '@angular/material/core';
import { MatSelectModule } from '@angular/material/select';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { CartItem } from '../../interfaces/cart_item';
import { RouterLink } from '@angular/router';

Vamos adicionar também o array de imports.

@Component({
  selector: 'app-cart',
  imports: [
    CommonModule,
    MatCardModule,
    MatDividerModule,
    MatFormFieldModule,
    MatIconModule,
    MatOptionModule,
    MatSelectModule,
    MatButtonModule,
    RouterLink
  ],

Agora, precisamos adicionar os métodos. Vamos colocar a nomenclatura dos métodos para, depois, fazer essa implementação. Só para conseguir fazer com que aqueles erros parem e conseguir rodar a aplicação.

export class CartComponent {
  cartItems: CartItem[] = [];
  total: number = 0;

  getQuantities(currentQuantity: number): number[] {
    const maxQuantity = Math.max(currentQuantity, 10);
    return Array.from({ length: maxQuantity }, (_, i) => i + 1);
  }

  updateQuantity(productId: number, newQuantity: number) {}  


  removeItem(productId: number) {}


  finalizePurchase() {}


  continueShopping() {}
}

Agora, os erros pararam e podemos adicionar esse componente na página de checkout.

Integração com a página de checkout

No checkout.component.html, adicionaremos o componente de carrinho:

<section>
  <img src="assets/images/mini-banner.png" alt="">
  <app-cart></app-cart>
</section>

No checkout.component.ts, importaremos o CartComponent para evitar erros:

import { Component } from '@angular/core';
import { CartComponent } from '../../components/cart/cart.component';

@Component({
  selector: 'app-checkout',
  imports: [CartComponent],
  templateUrl: './checkout.component.html',
  styleUrl: './checkout.component.css'
})
export class CheckoutComponent {

}

Configuração de rotas

Para redirecionar ao clicar no ícone de carrinho, adicionaremos uma nova rota no app.routes.ts:

{ path: 'checkout',
component: CheckoutComponent
},

Em seguida, no header.html, adicionaremos um routerLink ao ícone de carrinho:

<mat-toolbar>
  <img src="assets/images/logo.png" class="logo">
  <div class="toolbar-buttons">
    <button mat-icon-button aria-label="Search">
      <mat-icon>search</mat-icon>
    </button>
    <button [routerLink]="['/checkout']" mat-icon-button aria-label="Cart">
      <mat-icon>shopping_cart</mat-icon>
    </button>
  </div>
</mat-toolbar>

Testando a aplicação

Após configurar tudo, testaremos a aplicação:

ng serve

Ao clicar no ícone de carrinho, seremos redirecionados para a tela de checkout, que possui o header, footer, mini-banner e o componente de carrinho, que ainda está vazio.

Próximo passo

No próximo vídeo, implementaremos a lógica para adicionar itens ao carrinho.

Sobre o curso Angular e Supabase: refinando a aplicação com SSR

O curso Angular e Supabase: refinando a aplicação com SSR possui 164 minutos de vídeos, em um total de 58 atividades. Gostou? Conheça nossos outros cursos de Angular em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Angular acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas