Hemos dicho en el concepto anterior que en Angular se delega todas las responsabilidades de acceso a datos (peticiones y envío de datos) y lógica de negocios en otras clases que colaboran con las componentes y son llamados servicios.
Veremos ahora como recuperar datos de un servidor web implementando dicha actividad en un servicio.
Confeccionar una aplicación que recupere una respuesta en JSON de la dirección:
https://ejerciciostutorialesya.com/vue/datos.php
La estructura del archivo JSON es:
[
{
"codigo": 1,
"descripcion": "papas",
"precio": 12.33
},
{
"codigo": 2,
"descripcion": "manzanas",
"precio": 54
}
]
Mostrar en una tabla HTML todos los artículos recuperados.
La recuperación de datos se debe hacer en un servicio.
Desde la línea de comandos de Node.js procedemos a crear el proyecto013:
f:\angularya> ng new proyecto013
Crearemos el servicio que recuperará desde un servidor la lista de artículos
f:\angularya\proyecto13\> ng generate service articulos
Con el comando anterior estamos creando la clase 'ArticulosService'
Se crean dos archivos.
El código generado de la clase 'ArticulosService' es:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ArticulosService {
constructor() { }
}
Lo modificamos por el siguiente código que permita recuperar desde un servidor web el archivo JSON:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ArticulosService {
constructor(private http: HttpClient) { }
retornar() {
return this.http.get("https:///vue/datos.php");
}
}
El archivo 'app.module.ts' se modifica con el siguiente código (se importa la clase HttpClientModule):
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {HttpClientModule} from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Ahora veremos como consumimos el servicio desde nuestra componente. Procedemos a modificar la componente que se crea por defecto 'AppComponent' que tiene por responsabilidad mostrar en la página el listado de artículos:
import { Component, OnInit } from '@angular/core';
import { ArticulosService } from './articulos.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
articulos: any;
constructor(private articulosService: ArticulosService) {}
ngOnInit() {
this.articulosService.retornar()
.subscribe( result => this.articulos = result)
}
}
Primero importamos el servicio llamado ArticulosService que se almacena en el archivo 'articulos.service.ts':
import { ArticulosService } from './articulos.service';
Para inyectar el objeto de la clase 'ArticulosService' que crea Angular en forma automática lo hacemos en el parámetro del constructor:
constructor(private articulosServicio: ArticulosService) {
}
Se almacena en el atributo 'articulosServicio' la referencia del objeto de la clase 'ArticulosService' que crea Angular.
En el método ngOnInit actualizamos la propiedad 'articulos' con el resultado devuelto:
ngOnInit() {
this.articulosService.retornar()
.subscribe( result => this.articulos = result)
}
Esta asignación dispara la actualización de la página HTML.
Falta que codifiquemos la vista con los datos recuperados:
app.component.html
<div *ngIf="articulos!=null; else espera">
<table border="1">
<tr>
<td>Codigo</td><td>Descripcion</td><td>Precio</td>
</tr>
<tr *ngFor="let art of articulos">
<td>{{art.codigo}}</td>
<td>{{art.descripcion}}</td>
<td>{{art.precio}}</td>
</tr>
</table>
</div>
<ng-template #espera>Esperando datos...</ng-template>
Si ejecutamos ahora el proyecto013 veremos en el navegador el listado de artículos, pero ahora recuperados de un servidor y no extraidos de un vector como en el concepto anterior:
ng server -o
Podemos probar esta aplicación en la web aquí.