Como fazer requisições AJAX com Angular 2+

Uma das tarefas mais comuns para quem trabalha com front-end é a comunicação com o back-end. É ele quem provê as informações necessárias para a aplicação front funcionar. É muito comum que esta comunicação seja feita através do protocolo HTTP.

Como fazer requisições AJAX com Angular 2+

Indo direto ao ponto, o Angular fornece a classe HttpClientque faz as requisições HTTP:

this.http.get('algum endereço http')
    .subscribe(responseData => console.log(responseData));
The HttpClient in @angular/common/http offers a simplified client HTTP API for Angular applications that rests on the XMLHttpRequest interface exposed by browsers. Additional benefits of HttpClient include testability features, typed request and response objects, request and response interception, Observableapis, and streamlined error handling.

Antes de mais detalhes, para utilizar esta classe basta importar o módulo HttpClientModule e injetar a classe no construtor, como este outro exemplo:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
    selector: 'app-custom-selector',
    template: 'Hello'
})
export class MyTemplateComponent implements OnInit {
    constructor(private http: HttpClient) { }
    
    ngOnInit(): void {
        this.http
            .get('https://www.mocky.io/v2/5185415ba171ea3a00704eed')
            .subscribe(response => console.log(response));
    }
}

Estes dois exemplos mostram como podemos fazer uma requisição do tipo GET, mas esta mesma classe, HttpClient, tem outros métodos para POST, PUT e DELETE além de diversas outras opções. Neste post apenas mostrarei o GET mas os outros métodos não fogem muito deste formado.

Para simular um cenário um pouco mais realista, eu criei um projeto novo com o objetivo de consumir uma API e listar na tela os estados do Brasil.

Para criar o projeto utilizei o Angular CLI com o seguinte comando:

ng new meuProjetoTeste --prefix exe --style css --routing true

Após criar o projeto eu adicionei 3 arquivos:

  • estados.component.ts
    Componente responsável por exibir a lista de estados
  • estados.component.html
    Template utilizado pelo componente acima
  • estados.service.ts
    Classe responsável por efetuar as requisições HTTP para obter a lista de estados

app-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EstadosComponent } from './estados/estados.component';

const routes: Routes = [{
    path: 'estados',
    component: EstadosComponent
}];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { EstadosComponent } from './estados/estados.component';

@NgModule({
    declarations: [
        AppComponent,
        EstadosComponent
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

estados.component.html:

<div *ngFor="let estado of estados">{{estado.nome}}</div>

estados.component.ts:

import { Component, OnInit } from '@angular/core';
import { EstadosService } from './estados.service';

@Component({
    selector: 'exe-estados-lista',
    templateUrl: 'estados.component.html'
})
export class EstadosComponent implements OnInit {
    constructor(private estadosService: EstadosService) { }
    estados: any;

    ngOnInit() {
        this.estadosService.getUFs()
            .subscribe(response => {
                this.estados = response;
            });
    }
}

estados.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class EstadosService {
    constructor(private http: HttpClient) {

    }

    getUFs() {
        const url = 
            'https://servicodados.ibge.gov.br/api/v1/localidades/estados/';

        return this.http.get(url);
    }
}

Como dito anteriormente, para que nossa aplicação possa injetar o httpClienté necessário fazer um importno módulo e também declarar o componente estados.component:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { EstadosComponent } from './estados/estados.component';

@NgModule({
    declarations: [
        AppComponent,
        EstadosComponent // <<< Adicionar o componente
    ],
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule // << Adicionar o módulo
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

E finalmente é necessário mapear uma nova rota para exibirmos a listagem de estados:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EstadosComponent } from './estados/estados.component';

// Mapeamento da rota /estados
const routes: Routes = [{
    path: 'estados',
    component: EstadosComponent
}];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

Resultado ao chamar http://localhost:4200/estados no navegador:

Resultado final

Considerações

Primeiramente há muito o que abordar sobre este assunto. Aqui apenas demonstrei alguns exemplos bem simples que irei aprofundar em outros posts mas pode ser um ponto de partida para aqueles que estão começando com o Angular.