Platzi!
Las imagenes de la lista de productos no se están resolviendo, me da un error 404.
Cuando una aplicación deja de usar datos manuales y comienza a consumir información real desde una REST API, el proyecto da un salto significativo hacia un entorno profesional. Angular ofrece herramientas específicas para realizar estas conexiones de forma limpia y tipada, y aquí se explica paso a paso cómo lograrlo utilizando la Platzi Fakestore API, un recurso diseñado para practicar con una estructura de datos muy similar a la que encontrarías en producción.
¿Qué es la Platzi Fakestore API y por qué usarla?
La Platzi Fakestore API [0:22] es una API pública disponible en fakeapi.platzi.com, creada para que estudiantes practiquen con endpoints reales. Su diseño replica escenarios laborales concretos:
Un detalle importante de la estructura de datos es que cada producto ya no contiene una sola imagen, sino un array de imágenes [3:22], lo que permite construir galerías más ricas en la interfaz.
¿Cómo se configura HttpClient en Angular?
Antes de hacer cualquier llamada HTTP, es necesario habilitar el módulo correspondiente en la configuración global de la aplicación.
¿Qué se agrega en app.config?
Dentro del archivo app.config [3:55] se importa provideHttpClient desde @angular/common/http y se registra en el array de providers:
typescript import { provideHttpClient } from '@angular/common/http';
// Dentro de providers: providers: [ provideRouter(routes), provideHttpClient() ]
Este paso es obligatorio. Sin él, cualquier intento de inyectar el HttpClient en un servicio fallará.
¿Cómo se crea el servicio de productos?
Desde la terminal se genera un nuevo servicio dentro de la carpeta shared/services [2:38]:
bash ng generate service shared/services/product
Dentro del servicio se inyecta HttpClient usando la función inject [4:40]:
typescript import { inject, Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http';
@Injectable({ providedIn: 'root' }) export class ProductService { private http = inject(HttpClient);
getProducts() { return this.http.get<Product[]>('https://api.escuelajs.co/api/v1/products'); } }
El método get recibe un genérico que permite tipar la respuesta. Esto significa que le indicamos a Angular que esperamos un Product[], un array de productos, como resultado de esa petición.
¿Cómo se consume la API desde un componente?
Al cambiar de datos manuales a datos remotos, la interfaz Product necesita un ajuste: el campo image pasa a ser images: string[] [5:30]. Gracias al tipado estricto de TypeScript, el compilador señala inmediatamente todos los lugares donde se usaba el campo anterior, proporcionando feedback temprano para corregir errores antes de ejecutar la aplicación.
¿Dónde se renderiza la primera imagen del array?
En el componente de producto y en el header, donde antes se mostraba product.image, ahora se accede a la posición cero del array [6:40]:
typescript product.images[0]
En el componente de lista de productos se inyecta el servicio y se llama dentro del ciclo de vida ngOnInit [7:22]:
typescript private productService = inject(ProductService);
ngOnInit() { this.productService.getProducts().subscribe({ next: (data) => { this.products.set(data); }, error: (err) => { console.error(err); } }); }
El método subscribe recibe la información cuando la API responde. Con products.set(data) se actualiza la señal (signal) que alimenta la vista, y el bloque error permite gestionar fallos en la petición.
El resultado final es un e-commerce funcional conectado a una API real con doscientos productos, cada uno con título, precio y galería de imágenes. ¿Ya probaste conectar tu proyecto a esta API? Comparte tu experiencia y las dificultades que encontraste en los comentarios.
Cuando una aplicación deja de usar datos manuales y comienza a consumir información real desde una REST API, el proyecto da un salto significativo hacia un entorno profesional. Angular ofrece herramientas específicas para realizar estas conexiones de forma limpia y tipada, y aquí se explica paso a paso cómo lograrlo utilizando la Platzi Fakestore API, un recurso diseñado para practicar con una estructura de datos muy similar a la que encontrarías en producción.
La Platzi Fakestore API [0:22] es una API pública disponible en fakeapi.platzi.com, creada para que estudiantes practiquen con endpoints reales. Su diseño replica escenarios laborales concretos:
Un detalle importante de la estructura de datos es que cada producto ya no contiene una sola imagen, sino un array de imágenes [3:22], lo que permite construir galerías más ricas en la interfaz.
Antes de hacer cualquier llamada HTTP, es necesario habilitar el módulo correspondiente en la configuración global de la aplicación.
Dentro del archivo app.config [3:55] se importa provideHttpClient desde @angular/common/http y se registra en el array de providers:
typescript import { provideHttpClient } from '@angular/common/http';
// Dentro de providers: providers: [ provideRouter(routes), provideHttpClient() ]
Este paso es obligatorio. Sin él, cualquier intento de inyectar el HttpClient en un servicio fallará.
Desde la terminal se genera un nuevo servicio dentro de la carpeta shared/services [2:38]:
bash ng generate service shared/services/product
Dentro del servicio se inyecta HttpClient usando la función inject [4:40]:
typescript import { inject, Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http';
@Injectable({ providedIn: 'root' }) export class ProductService { private http = inject(HttpClient);
getProducts() { return this.http.get<Product[]>('https://api.escuelajs.co/api/v1/products'); } }
El método get recibe un genérico que permite tipar la respuesta. Esto significa que le indicamos a Angular que esperamos un Product[], un array de productos, como resultado de esa petición.
Al cambiar de datos manuales a datos remotos, la interfaz Product necesita un ajuste: el campo image pasa a ser images: string[] [5:30]. Gracias al tipado estricto de TypeScript, el compilador señala inmediatamente todos los lugares donde se usaba el campo anterior, proporcionando feedback temprano para corregir errores antes de ejecutar la aplicación.
En el componente de producto y en el header, donde antes se mostraba product.image, ahora se accede a la posición cero del array [6:40]:
typescript product.images[0]
En el componente de lista de productos se inyecta el servicio y se llama dentro del ciclo de vida ngOnInit [7:22]:
typescript private productService = inject(ProductService);
ngOnInit() { this.productService.getProducts().subscribe({ next: (data) => { this.products.set(data); }, error: (err) => { console.error(err); } }); }
El método subscribe recibe la información cuando la API responde. Con products.set(data) se actualiza la señal (signal) que alimenta la vista, y el bloque error permite gestionar fallos en la petición.
El resultado final es un e-commerce funcional conectado a una API real con doscientos productos, cada uno con título, precio y galería de imágenes. ¿Ya probaste conectar tu proyecto a esta API? Comparte tu experiencia y las dificultades que encontraste en los comentarios.
Platzi!
Las imagenes de la lista de productos no se están resolviendo, me da un error 404.
Por si tienen problemas al tratar de visualizar las imágenes es un problema de la api, pero aquí les comparto mi servicio con la solución para que puedan ver las imágenes en el front
import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { map } from 'rxjs/operators';
import { Product } from '../models/product.model';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private http = inject(HttpClient);
constructor() { }
getProducts(){
return this.http.get<Product[]>('https://api.escuelajs.co/api/v1/products').pipe(
map(products =>
products.map(product => ({
...product,
images: product.images.map(image =>
this.cleanAndParseImageUrl(image)
)
}))
)
);
}
private cleanAndParseImageUrl(image: string): string {
let cleanedImage = image.replace(/^\["?|"?]$/g, '');
try {
cleanedImage = JSON.parse(cleanedImage);
} catch (error) {
//
}
return cleanedImage;
}
}
```*import* { HttpClient } *from* '@angular/common/http';*import* { Injectable, inject } *from* '@angular/core';*import* { map } *from* 'rxjs/operators';*import* { Product } *from* '../models/product.model';
@Injectable({ providedIn: 'root'})*export* class ProductService { private http = inject(HttpClient);
  constructor() { }
  getProducts(){ *return* *this*.http.get\<Product\[]>('https://api.escuelajs.co/api/v1/products').pipe( map(products => products.map(product => ({ ...product, images: product.images.map(image => *this*.cleanAndParseImageUrl(image) ) })) ) ); }
  private cleanAndParseImageUrl(image: string): string { let cleanedImage = image.replace(/*^*\\\["?|"?]*$*/g, ''); *try* { cleanedImage = JSON.parse(cleanedImage); } *catch* (error) { *//* } *return* cleanedImage; }}
en esta pagina puede tomar el json de respuesta de su api y se las traduce a la interface correspondiente según el lenguaje que seleccionen .
Las imágenes siguen fallando, una forma fácil de solucionarlas es la siguiente:
import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { map } from 'rxjs/operators';
import { Product } from '../models/product.model';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private http = inject(HttpClient);
constructor() { }
getProducts(){
return this.http.get<Product[]>('https://api.escuelajs.co/api/v1/products').pipe(
map(products =>
products.map(product => ({
...product,
images: product.images.map(() =>
'https://picsum.photos/640/640?r=' + Math.random()
)
}))
)
);
}
}
La verdad, queria sentirme comodo que funcionara entonces use esta temporalmente esta API.
Sin editar el modelo.
Ya si quieres corregir el bug de las imagenes de la API, lean a mis companeros.
Pero siento que es frustrante porque no podemos editar la API del backend, entonces como full stack lo haria crearia mi propia API, pero como frontend solo le diria a los que trabajan en backend que su API, no funciona que la corrijan, y por ultimo en llegado caso, si agregaria codigo de mas para solucionar el error del backend.

Algunas imagenes en el Json llegan con errores en las urls, por ello no se renderizan y angular las tiene por sospechosas. Andrés Sanchez, puso en los comentarios una solución con expresiones regulares. muy interesante.
Tengo una duda estoy haciendo el curso y todo va bien pero al momento de ver los resultados todo esta en blanco el error dice que las imagenes de la api no son seguras y angular no lo renderiza necesito ayuda porfa
Hay varias extensiones en VS Code que permiten consultar API's desde el editor de código.
POSTMAN:

THUNDER CLIENT:

Ambas son muy buenas y prácticas.
Hola!! estoy haciendo el curso tal y como lo esta haciendo Nico en los videos pero la API parece no funcionar, tengo todo igual y no me trae los productos a mi app. No se que pueda estar pasando.
no se visualizan las imagenes del api