No tienes acceso a esta clase

¬°Contin√ļa aprendiendo! √önete y comienza a potenciar tu carrera

√öltima oportunidad para asegurar tu aprendizaje por 1 a√Īo a precio especial

Antes: $249

Currency
$189/a√Īo

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

0D
6H
43M
59S

Solicitudes PUT y PATCH

6/23
Recursos

Los endpoints GET se utilizan para la obtención de datos, los endpoints POST para crearlos. Es momento de actualizarlos con PUT y PATCH.

PUT vs. PATCH, ¬Ņcu√°l es la diferencia?

Técnicamente, los endpoints PUT deberían recibir todos los datos del registro a actualizar. Por ejemplo, el título, la descripción, el precio, la categoría, etc. En cambio, PATCH debería solo recibir un campo individual a actualizar como solo el título, o solo la categoría.

De todos modos, también puedes utilizar endpoints del tipo PUT que reciban un solo dato a actualizar. Ten en cuenta que PUT es mucho más utilizado que PATCH, pero si quieres refinar y ser estricto con tu backend y seguir a raja tabla las buenas prácticas, PATCH es ideal para este tipo de actualizaciones de tus datos.

Como generar una actualización de registros

Para las solicitudes PUT y PATCH y generar una actualización de registros sigue los siguientes pasos.

1. Crea las interfaces necesarias

Crea las interfaces necesarias para actualizar los datos. Recuerda que la interfaz CreateProducto extendía de Product y a su vez omita los campos que no necesita utilizar.

// interfaces/producto.interface.ts
export interface Product {
  id: number;
  name: string;
  precio: number;
  description: string;
  image: string;
  category?: Category;
}

export interface CreateProducto extends Omit<Product, 'id' | 'category'> {
  idCategory: string;
}

A partir de aqu√≠, crea la interfaz UpdateProducto que extiende de CreateProducto y a su vez utiliza una nueva caracter√≠stica de TypeScript llamada Partial<> que coloca como opcionales todos los campos. Al ser todos los campos opcionales, puedes utilizar esta interfaz para solicitudes PUT o PATCH seg√ļn tengas la necesidad.

// interfaces/producto.interface.ts
export interface UpdateProducto extends Partial<CreateProducto> { }

2. Maneja interfaces para HTTP

Utiliza estas nuevas interfaces en el servicio para realizar peticiones HTTP

// services/api.service.ts
@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(
    private http: HttpClient,
  ) { }

 // ...

  updateProductPUT(idProduct: number, body: UpdateProducto): Observable<Product> {
    return this.http.put<Product>(`https://example.com/api/productos`, body);
  }

  updateProductPATCH(idProduct: number, body: UpdateProducto): Observable<Product> {
    return this.http.patch<Product>(`https://example.com/api/productos`, body);
  }
}

Ya sea que los endpoints del backend sean PUT o PACH, podrás realizar la solicitud y mantener tus datos tipados y tu aplicación más segura de errores.

3. Haz la solicitud para actualizar el producto

Finalmente, desde tu componente, realiza la solicitud para actualizar el producto. Cuando recibas el producto actualizado, deber√°s reemplazarlo por el producto viejo en tu lista de productos.

// components/catalogo/catalogo.component.ts
updateProduct(idProduct: number): void {
    const body: UpdateProducto = {
      name: 'Nuevo nombre del producto',
    };
    this.apiService.updateProductPATCH(idProduct, body)
      .subscribe(p => {
        // Reemplazamos el producto actualizado en el Array de productos
        const index = this.productos.findIndex(product => product.id === p.id);
        this.productos[index] = p;
      });
}

Si no utilizas PATCH y todos tus endpoints son PUT, eso est√° bien. No tiene que preocuparte.


Contribución creada por: Kevin Fiorentino.

Aportes 20

Preguntas 5

Ordenar por:

¬ŅQuieres ver m√°s aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Yo hice esta solución que se actualice tanto en la sección de show cart como en pantalla generar
<updateProduct(){
    const changes: UpdateProduct = {
      title: 'Nuevo title',
      description: 'Esta es un prueba',
    }
    const id = this.productChosen.id;
    this.productsService.update(id,changes).subscribe(data =>{
      const productIndex = this.products.findIndex(
        item =>item.id ==this.productChosen.id
      );
      this.products[productIndex] = data;
      this.productChosen = data;
    })
  }> 

Pasa solucionar el problema de actualizar el producto en detalle solo hay que actualizar la variable productChosen con data.

updateProduct(){
    const changes = {
      title: 'Nuevo titulo klk',
    }
    const id = this.productChosen.id;
    this.productService.update(id,changes)
    .subscribe(data => {
      console.log('Updated:', data);
      const productIndex = this.products.findIndex(item => item.id === this.productChosen.id);
      this.products[productIndex] = data;
      this.productChosen = data;
    })
    
  }

Intenté hacerlo con patch y no funciona, esto es porque en el backend no hay un metodo con el llamado patch(por si a alguien mas le pasa)

Me ha gustado la forma en que se definen las interfaces con el uso de la palabra Partial y de esta manera todos los campos del objeto son opcionales.

Si siguieron mi consejo de separar el detalle de producto en un componente nuevo, puedes hacer las siguientes modificaciones para que la información se actualice cuando actualices el producto:

product-detail.component.ts

  @Output() productUpdated = new EventEmitter<Product>();

updateProduct(id: string){
    const changes: UpdateProductDTO = {
      title: 'Producto Editado v2'
    };
    this.productsService.update(id, changes)
    .subscribe(data=>{
      this.product = data;
      this.productUpdated.emit(this.product);
    })
  }

products.component.html

<app-product-detail
            *ngIf="productChosen"
            [product]="productChosen"
            (productUpdated)="onUpdatedProduct($event)"
        ></app-product-detail>

products.component.ts

  onUpdatedProduct(data:Product){
    const productIndex = this.products.findIndex(item => item.id === data.id)
    this.products[productIndex] = data;
  }

Otra forma de crear el DTO para actualizar seria:

interface UpdateProductDTO extends Partial<Omit<Product, 'id', 'category'>> {
	categoryId: number;
}

Hay otra manera de usar el Partial sin crear una nueva interfaz y es directamente en la funcion de update del product service.

update(dto: Partial <CreateProductDTO>){
    return this.http.patch<Product>(this.apiUrl, dto);
  }

Para que el cambio se vea reflejado en la vista Detalles solo es asignarle a
this.productChosen = data;

No se que rayos hice pero no tuve la necesidad de hacer nada m√°s, el productChosen y el array se actualizaron solos :V

Genial el partial, con respecto a PUT y PATCH yo elegir√≠a PATCH, ya que la mayor√≠a de las veces solo que queremos actualizar un atributo o propiedad en espec√≠fico, aunque como soy un poco purista jejeje si fue un proyecto personal me dar√≠a el tiempo para tener los dos m√©todos en mi backend ūüôā. Para solucionar la actualizaci√≥n del detalle del producto lo mejor ser√≠a no realizar un get para ver lo detalles sino compartir los datos de la primera llamada en nuestro componente

El comentario anterior se me fue mal, aquí dejo el bloque de código ```js updateProduct() { const change: UpdateProductDTO = { title: 'Cambio titulo', } const id = this.productChossen.id; this.productService.update(id, change) .subscribe(data => { const productIndex = this.products.findIndex(item => item.id === id); this.products[productIndex] = data; this.productChossen = data; //Se asigna el nuevo valor de data al producto seleccionado }); } ```  updateProduct() {    const change: UpdateProductDTO = {      title: 'Cambio titulo',    }    const id = this.productChossen.id;    this.productService.update(id, change)    .subscribe(data => {      const productIndex = this.products.findIndex(item => item.id === id);      this.products\[productIndex] = data;      this.productChossen = data; //Se asigna el nuevo valor de data al producto seleccionado    });  }
Creo que la forma más fácil de actualizar también el producto seleccionado en el slide, es la siguiente: `  updateProduct() {    const change: UpdateProductDTO = {      title: 'Cambio titulo',    }    const id = this.productChossen.id;    this.productService.update(id, change)    .subscribe(data => {      const productIndex = this.products.findIndex(item => item.id === id);      this.products[productIndex] = data;      this.productChossen = data; //Se asigna el nuevo valor de data al producto seleccionado    });  }`
Hola, yo solo le agregue esa línea de código al subcribe ![](https://static.platzi.com/media/user_upload/image-dc52155b-c7ba-4302-83e7-3c75e446ada7.jpg) ![]()this.productChosen.title=this.products\[productIndex].title; Me funciono pero no se si está bien jaja.

Est√° buenisimo este curso!
Me encantarían más cursos de Nico para Angular 16!

nico buenas tardes una pregunta que seria mas recomendable luego de actualizar hacer una peticion get con el nuevo array o solo actualizar el array con el elemento modificado

Esta clase es una hermosura! he aprendido detalles MEGA IMPORTANTES con respecto al tema de las interfaces DTO !

Para recordar:

update(id: string, dto: UpdateProductDTO) {
    return this.http.put<Product>(`${this.apiUrl}/${id}`, dto);
    //* PUT: enviar toda la información
    //* PATCH: enviar solo la información modificada
  }

Nota aparte: confunde la pronunciación de put con pot.

mi solución:

  updateProduct() {
    const changes: UpdateProductDTO = {
      title: 'Nuevo Titulo Actualizado'
    }

    const id = this.productChosen.id;
    this.productsService.update(id, changes)
    .subscribe(
      data => {
        const productIndex = this.products.findIndex(p => p.id === id);
        this.products[productIndex] = data;
        this.productChosen = data;
        console.log(data);
    });
  }

Para solucionar actualizar producto

 updateProduct() {
    const changes = {
      title: 'Nuevo Producto',
    }

    const id = this.product.id;
    this.productsService.update(id, changes).subscribe(
      (product: Product) => {
        const productId = this.products.findIndex(p => p.id === id);
        this.products[productId] = product;
        this.product = product;
       console.log(product);
    });

  }