Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 7

Qui la parte precedente dell’articolo: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 6

Eseguire la chiamata all’inizializzazione dell’applicazione

La chiamata al servizio di recupero della lista di utenti va effettuata al caricamento dell’applicazione, in modo che essi siano subito disponibili per la visualizzazione.
Per fare questo dobbiamo modificare la classe “app.component.ts”, effettuando le seguenti operazioni:

  • Iniettare il Service nell’app, passandolo come parametro al suo costruttore
  • Far implementare alla classe AppComponent l’interfaccia OnInit
  • Inserire la chiamata al metodo del Service all’interno del metodo ngOnInit()

Per il primo punto, aggiungiamo quindi un costruttore per la classe, passandogli il Service nel modo seguente:

  constructor(private userService: UserApiService) { }

Per il secondo punto, modifichiamo la definizione della classe come segue:

export class AppComponent implements OnInit

Per implementare correttamente l’interfaccia occorre fornire l’implementazione dei metodi previsti che, in questo caso, si riducono al solo metodo ngOnInit(). Sfruttiamo l’aiuto dei quick fix di Spring Tool Suite dicendogli di fornirci l’implementazione:
54 - Spring Tool Suite Angular AppComponent implements OnInitIl metodo viene creato con questa implementazione:

  ngOnInit(): void {
    throw new Error("Method not implemented.");
  }

Cancelliamo il contenuto e inseriamo invece al suo interno la chiamata al metodo getUsers() che abbiamo definito nel nostro Service, seguito dal metodo then(), invocato quando il risultato della chiamata è disponibile, all’interno del quale non facciamo altro che assegnare all’array “users” della nostra classe il valore restituito dalla chiamata. Il corpo del metodo ngOnInit() diventa quindi il seguente:

  ngOnInit(): void {

    this.userService.getUsers().then(u => this.users = u);
  }

Il codice completo della classe AppComponent a questo punto è il seguente:

import { Component, OnInit } from '@angular/core';
import { User } from './models/user';
import { UserApiService } from './services/user-api.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

  title = 'davismol.net Tutorial';
  users: User[];

  constructor(private userService: UserApiService) { }

  ngOnInit(): void {

    this.userService.getUsers().then(u => this.users = u);
  }
}

55 - Spring Boot Angular call Service method inside App ngOnInitC’è ancora una cosa che dobbiamo fare, prima di poter utilizzare correttamente il nostro “UserApiService” per recuperare la lista di utenti dal back-end Spring Boot e cioè aggiungere il servizio stesso all’array “provider” nel modulo dell’app.
Andiamo quindi “app.module.ts” e modifichiamo la riga:

providers: [] 

in

providers: [UserApiService]

56 - Spring Boot Angular add Service to module providers arrayA questo punto siamo pronti per fare un test di integrazione tra i due progetti.

Li mettiamo in esecuzione entrambi, sia il back-end Spring Boot che il front-end Angular. Al solito, il primo sarà in ascolto sulla porta 8080 mentre il secondo utilizzerà la 4200.
57 - Spring Boot and Angular projects running on different ports Non ci resta che aprire il browser e puntare all’indirizzo del progetto Angular. Qui dovremmo ottenere lo stesso risultato ottenuto in precedenza quando la lista di utenti era definita staticamente nella classe TypeScript dell’app Angular, con la differenza che questa volta gli utenti ci vengono forniti dal back-end tramite una chiamata alla relativa API esposta.
58 - Spring Boot and Angular application no data retrievedUn momento! Qualcosa è andato storto! Gli utenti non compaiono nell’apposita tabella.

Dal browser Chrome gli “Strumenti per Sviluppatori” premendo il tasto F12. A questo punto facciamo un refresh della pagina della nostra applicazione. Come possiamo vedere dalla nuova finestra di supporto allo sviluppo, si è verificato un errore:

Failed to load http://localhost:8080/users: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

59 - Spring Boot and Angular 4 No Access-Control-Allow-Origin headerQuesto si verifica perché il client e il server, essendo in esecuzione su due porte differenti, risultano su domini diversi e, per ragioni di sicurezza e di prevenzione di eventuali problematiche di CORS (Cross-Origin Resource Sharing), il server deve esplicitamente abilitare la ricezione di richieste provenienti da un dominio diverso.

Questo ovviamente è un problema solo in questa fase di sviluppo, in cui effettivamente i due progetti girano in modo indipendente. Quando andremo a distribuire l’applicazione creeremo invece, in fase di build, un unico pacchetto che conterrà sia il back-end che il front-end, quindi il problema non si porrà.

Per risolvere il problema in fase di sviluppo, andiamo nel nostro controller e abilitiamo la ricezione di richieste provenienti dal dominio del nostro progetto Angular, ovvero http://localhost:4200

Per farlo utilizziamo l’annotazione @CrossOrigin nel modo seguente:

@CrossOrigin(origins = "http://localhost:4200")
    @RequestMapping(value = "/users", method = { RequestMethod.GET })
    public List listAllUsers() {

60 - Spring Boot and Angular 4 CrossOrigin annotationRiavviamo il progetto Spring Boot e proviamo a refreshare la pagina web.
61 - Spring Boot and Angular 4 Service Data retrieved correctlyEcco che adesso la lista dei nostri utenti compare correttamente!

Controlliamo nuovamente la console degli Strumenti per Sviluppatori di Chrome, dove possiamo vedere che l’errore dovuto all’header ‘Access-Control-Allow-Origin‘ è sparito.
62 - Spring Boot and Angular 4 Error No Access-Control-Allow-Origin disappearedAbbiamo così integrato e fatto “parlare” tra di loro i due progetti Angular e Spring Boot, creando un servizio REST che ritorna la lista degli utenti al front-end Angular, che li renderizza in pagina tramite un apposito Component.

Vai alla parte successiva dell’articolo: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 8

This entry was posted in $1$s. Bookmark the permalink.

3 thoughts on “Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 7

  1. Pingback: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 6 | Dede Blog

  2. Pingback: Creare una web application con Spring Boot, MongoDB, Angular 4 e TypeScript e deployarla in cloud come Microsoft Azure Webapp – Parte 8 | Dede Blog

  3. Ottima guida ma io riscontro un problema. Nonostante abbia seguito passo passo la tua guida il back-end e Angular non comunicano…non mi viene restituito nessun errore in console, cosa potrebbe essere?

Leave a Reply to Giuliano Cancel reply

Your email address will not be published. Required fields are marked *