Tengo una solicitud de obtención en un componente que devuelve una respuesta.
getPaymentIntents():Observable<Payment>>{ const url: string = 'https://store.com//payments'; return this.http.get<Payment>> (url); }Los datos de respuesta se parecen a esto (el tipo "Pago")
[ { "id": "pi_3K4B432423dqM1gTYncsL", "amount": 2000, "amount_capturable": 0, "amount_received": 0, "application": null, "canceled_at": null, "cancellation_reason": null, "created": 1638911287, "currency": "usd", "customer": "cus_KjDBkdsaHIT6AN" }, { "id": "pi_3K4BW7EE9YQoA1qM1gTYncsL", "amount": 1000, "amount_capturable": 0, "amount_received": 0, "application": null, "canceled_at": null, "cancellation_reason": null, "created": 1638913687, "currency": "usd", "customer": "cus_KjDBkxEVHIT6AN" } ]Quiero que estos datos estén en una "Tabla de materiales" https://material.angular.io/components/table/overview
Pero solo quiero que muestre un subconjunto de los datos. (En el futuro, también querré combinar los datos de otra respuesta en la tabla)
El tipo que quiero pasar a la tabla como dataSource es este
export interface OrderToProcess{ Id: string, Amount: number, Currency: string } ¿Cómo hago para convertir un tipo en otro? Probé filter() map() object.entries() y estoy seguro de que no los estoy usando correctamente, pero ninguno parece hacer lo que busco.
¡Gracias por cualquier ayuda!
Supongo que solo necesitas hacer esto:
TS
... import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; ... // Declare your interface before declaring your Class, right after your imports export interface OrderToProcess{ Id: string, Amount: number, Currency: string } ... // In your class attributes declaration dataSource$: Observable<OrderToProcess[]>; ... constructor() { this.dataSource$ = this.getPaymentIntents() .pipe( map( (data:Payment[]) => { let ordersToProcess: OrderToProcess[] = data.map( payment => { Id: payment.id, Amount: payment.amount, Currency: payment.currency } ); return ordersToProcess; }) //end map rxjs ); //end pipe rxjs }Luego, en su HTML simplemente pase el dataSource$ observable a su tabla de materiales como de costumbre ([dataSource]="dataSource$")
NOTA: no estoy completamente seguro, pero tal vez incluso puedas simplificarlo más simplemente haciendo lo siguiente:
this.dataSource$ = this.getPaymentIntents() .pipe( map( (data:Payment[]) => data.map( payment => { Id: payment.id, Amount: payment.amount, Currency: payment.currency } )));De hecho, estás buscando un mapa . Suponiendo que tenemos la siguiente función para simular su llamada HTTP:
// Imports needed for rest of example code import { map, Observable, of } from 'rxjs'; /** * getPaymentIntents mocks HTTP call with static data */ getPaymentIntents(): Observable<any> { return of([ { id: 'pi_3K4B432423dqM1gTYncsL', amount: 2000, amount_capturable: 0, amount_received: 0, application: null, canceled_at: null, cancellation_reason: null, created: 1638911287, currency: 'usd', customer: 'cus_KjDBkdsaHIT6AN', }, { id: 'pi_3K4BW7EE9YQoA1qM1gTYncsL', amount: 1000, amount_capturable: 0, amount_received: 0, application: null, canceled_at: null, cancellation_reason: null, created: 1638913687, currency: 'usd', customer: 'cus_KjDBkxEVHIT6AN', }, ]); } }Puede asignar a su tipo en su componente usando lo siguiente (o algo similar:
// Table columns displayedColumns: string[] = ['id', 'amount', 'currency']; // Our table data source dataSource$: Observable<OrderToProcess[]>; constructor() { this.dataSource$ = this.getPaymentIntents().pipe( // Map data to an array of type OrderToProcess. map((data) => { let transformedData: OrderToProcess[] = []; for (let i = 0; i < data.length; i++) { transformedData.push({ Id: data[i].id, Amount: data[i].amount, Currency: data[i].currency, }); } return transformedData; }) ); }Y para mostrarlos en tu tabla:
<table mat-table [dataSource]="dataSource$" class="mat-elevation-z8"> <ng-container matColumnDef="id"> <th mat-header-cell *matHeaderCellDef>ID</th> <td mat-cell *matCellDef="let element">{{element.Id}}</td> </ng-container> <ng-container matColumnDef="amount"> <th mat-header-cell *matHeaderCellDef>Amount</th> <td mat-cell *matCellDef="let element">{{element.Amount}}</td> </ng-container> <ng-container matColumnDef="currency"> <th mat-header-cell *matHeaderCellDef>Currency</th> <td mat-cell *matCellDef="let element">{{element.Currency}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table>Si pega esto en su proyecto, creo que debería ayudarlo a lograr lo que está buscando.