Estoy desarrollando una aplicación angular en la que llamo al siguiente punto final desde la API de CoinGeko que me proporciona gráficos de mercado:
https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=cad&days=7&interval=daily
Devuelve algo como lo siguiente:
{ "prices": [ [ 1643414400000, 48329.41585141156 ], [ 1643494489000, 48870.92050262988 ] ], "market_caps": [ [ 1643414400000, 915485662636.434 ], [ 1643494489000, 925791491728.014 ] ], "total_volumes": [ [ 1643414400000, 24532182816.548737 ], [ 1643494489000, 18070713602.083645 ] ] }A partir de esta respuesta, necesito trabajar solo en la propiedad "precios".
Es una matriz de matrices con marca de tiempo UNIX y el precio Crypto.
Entonces, lo que estoy tratando de alcanzar es tener dos matrices diferentes donde:
El siguiente fragmento muestra mi intento:
Interfaces.ts
export interface Chart { prices: Array<DatePrice>; market_caps: Array<DatePrice>; total_volumes: Array<DatePrice>; } export interface DatePrice { unixDate: string[]; price: number[]; }componente.ts
[...] coinChart: Chart[]; sevenDayPrices: number[]; sevenDayDates: Date[]; ngOnInit() { this._apiService .getWeeklyChartData() .subscribe(chartData => { this.coinChart = chartData; console.log(chartData); chartData.map(x => x.prices.map(daysPrice => { console.log(daysPrice.price); this.sevenDayPrices = daysPrice.price }) ); }Desafortunadamente no funciona. Lo que me gustaría lograr es algo como:
sevendayprices = [48329.4158514115, 48870.92050262988] sevendaydates = [1643414400000, 1643494489000]¿Cómo puedo alcanzar este objetivo?
~SRJ
Parece que lo que estás haciendo está bastante bien. En cuanto a la solución, está recibiendo una matriz de matrices y su interfaz de gráficos ya la contiene. Sería mucho mejor usar Array en lugar de otra interfaz DatePrice porque no la necesita. Así que lo primero es lo primero, arreglar esto:
//this is wrong coinChart: Chart[]; //use this instead coinChart: Chart; //since you want in readable date, use sevenDayDates: string[];//instead of dateAquí va la lógica más fácil para dividir ambas matrices:
ngOnInit() { this._apiService .getWeeklyChartData() .subscribe(chartData => { this.coinChart = chartData; this.sevenDayDates = this.coinChart.prices.map(function(tuple) { return new Date(tuple[0]).toLocaleTimeString() }); this.sevenDayPrices = this.coinChart.prices.map(function(tuple) { return tuple[1] }); }Déjame saber si eso funciona. Si su interfaz es adecuada, literalmente puede usar todas estas propiedades en su respuesta chartData. Y espero que en la llamada a la API, devuelva el tipo de gráfico en lugar del tipo de gráfico [].
Si entiendo bien su necesidad, el siguiente fragmento podría ser el truco:
const response = { prices: [ [ 1643414400000, 48329.41585141156 ], [ 1643494489000, 48870.92050262988 ] ], market_caps: [ [ 1643414400000, 915485662636.434 ], [ 1643494489000, 925791491728.014 ] ], total_volumes: [ [ 1643414400000, 24532182816.548737 ], [ 1643494489000, 18070713602.083645 ] ] } ... // Interface export interface MyObjInterface = { prices: string[], dates: string[] } ... // inside class, above constructor() myPrices: number[] obj: MyObjModel ngOnInit() { this.myPrices = response.prices.flat() this.obj = { prices: this.checkDotInNumber(myPrices, true), dates: this.checkDotInNumber(myPrices, false) } console.log(this.obj) } checkDotInNumber(arr, hasDot): string[] { const a = arr.flat(); let includeDot = (num) => { return num.toString().includes('.') } return (hasDot) ? a.filter(x => includeDot(x)) : a.filter(x => !includeDot(x)) }##Explicación:##
Recibes un objeto como respuesta, por lo que puedes acceder a la propiedad "prices" simplemente navegando a "response.prices" (con "response" me refiero a mi objeto que es el mismo que tienes en tu suscripción: chartData).
Al tener "response.prices", puede realizar alguna operación en la matriz y crear un nuevo objeto que denominé "this.obj" con dos propiedades: "prices" con la matriz de precios y "dates" con la matriz de fechas.
##¿Por qué he creado un nuevo objeto?##
Porque "this.myobj" se puede desestructurar para que pueda acceder rápida y fácilmente a su propiedad cuando la necesite. Así por ejemplo:
const {prices, dates} = this.myobj console.log(prices, dates);##Insinuación##:
El objeto devuelve dos matrices de cadena, por lo que si necesita trabajar con un número, debe convertir la matriz de elementos en un número nuevamente.
##ACTUALIZAR:##
Según los comentarios de The Fool, tiene razón, el rendimiento es importante, por cierto, es importante encontrar un compromiso entre el rendimiento y la legibilidad.
Así que mi otra sugerencia para lograr tu objetivo es:
const mapper = new Map(response.prices); const prices = Array.from(mapper.values()); const dates = Array.from(mapper.keys()); console.log(dates, prices)Encuentro esta manera más simple, más rápida y más legible.