Я пытаюсь использовать новый публичный API V2 CoinMarketCap, но у меня возникают некоторые трудности с этим.
JSON:
https://api.coinmarketcap.com/v2/ticker/?limit=10
моя модель монеты:
export class Coins {
id: string;
name: string;
symbol: string;
rank: number;
price_usd: number;
price_btc: number;
_24h_volume_usd: number;
market_cap_usd: number;
available_supply: number;
total_supply: number;
percent_change_1h: number;
percent_change_24h: number;
percent_change_7d: number;
last_updated: number;
}
моя служба:
urlBase = 'https://api.coinmarketcap.com/v2/ticker/?limit=10';
getCoins() {
return Observable
.timer(0, 5000)
.flatMap(() => this.http.get(this.urlBase))
.pipe(
map(res => res),
catchError(this.handleError)
)
}
мой компонент:
coins: Coins[];
getCoins() {
this.coinsService.getCoins().subscribe(
data => {
this.coins = data;
});
}
мой HTML:
<div class = "card card-inverse" *ngFor = "let coin of coins">
выход:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type
'object'. NgFor only supports binding to Iterables such as Arrays.
любое предложение?
Спасибо
Попробуйте использовать * ngFor = «пускать монету в монеты».
Может ли это помочь? stackoverflow.com/questions/39761673/…
Возможный дубликат ОШИБКА: NgFor поддерживает привязку только к Iterables, таким как массивы



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы получили эту ошибку только потому, что выполняете итерацию объекта. Вам нужен массив объектов для перебора.
Попробуйте код ниже в вашем файле mycomponent.
getCoins() {
this.coinsService.getCoins().subscribe(
data => {
let coins = [];
for (let key in data) {
coins.push(data['key']);
}
this.coins = coins;
});
}
Из данных api, которые вы показываете, я вижу, что вы назначаете this.coins объекту, а не массиву. Вы должны сначала преобразовать его в массив, а затем назначить его this.coins.
getCoins() {
this.coinsService.getCoins().subscribe(
data => {
this.coins = [];
for(let key in data){
this.coins.push(data[key]);
}
});
}
Или вы также можете сделать этот способ для преобразования объекта в массив.
getCoins() {
this.coinsService.getCoins().subscribe(
data => {
this.coins = [];
Object.keys(data).map((key)=>{ this.coins.push(data[key]) });
});
}
В вашем служебном файле
getCoins() {
return this.http.get(this.urlBase).pipe(map(res => res = res.json()['data']))
}
Рабочий ДЕМО
Привет, Амит, спасибо за ответ. В обоих случаях у меня есть вывод: ERROR TypeError: Невозможно прочитать свойство push of undefined.
Во время декларации инициализируйте свои монеты как coins : Coins[] = [];.
@Michael Если вы не инициализируете массив coins с пустым массивом [], вам придется использовать временный массив, а затем назначить его. Лучше всего, если вы инициализируете внутри самой функции, если не во время объявления.
хорошо, у меня нет ошибки, но на экране ничего не отображается. Как это должно быть в html?
Измените свой служебный файл соответствующим образом, и я добавил демонстрацию для вашей справки.
Да, у меня работает !! Вместо res = res.json () только res = res
this.coins = data.json() или вы можете использовать наблюдаемый.
в html <div class = "card card-inverse" *ngFor = "let coin of coins | async">
в компоненте
coins: Observable<Coin[]>;
getCoins() {
this.coins = this.coinsService.getCoins();
}
в сервисе:
getCoins(): Observable<any> {
const api = 'https://api.coinmarketcap.com/v2/ticker/?limit=10';
return this.httpClient.get(api);
}
в вашем компоненте:
getCoins() {
this.appService
.getCoins()
.subscribe(
data => this.coins = data.data,
error => console.info(error)
);
}
coinKeys(coins) {
return Object.keys(coins);
}
в шаблоне:
<tr *ngFor = "let k of coinKeys(coins )">
<td>{{ coins[k].id }}</td>
</tr>
Хорошо, я попробовал ваш пример и вижу некоторые проблемы с ним. Не уверен, чего вы пытаетесь достичь с помощью таймера, поэтому не усложняйте его. Я получаю такой ответ: { data: [], metadata: [] }
Итак, я предполагаю, что на вашей карте вам нужно сопоставить, например, этот map(res => res.data), чтобы отобразить свойство данных, например
Я переписал простой пример:
getCoins() {
const urlBase = "https://api.coinmarketcap.com/v2/ticker/?limit=10";
this.http
.get(urlBase)
.pipe(map(res => res))
.subscribe(res => console.info(res));
}
Чтобы получить свойство данных, измените приведенную выше карту на .pipe(map(res => res.data)).
Чтобы избежать ошибки ts, вы также можете ввести ее:
.pipe(map((res: { data: any; metadata: any }) => res.data))
Вам также понадобится дополнительное сопоставление данных, чтобы соответствовать вашему интерфейсу Coin.
Я могу больше помочь, если ты не сможешь найти способ сделать это;)
Привет, Мегаклис, спасибо за ответ. У меня есть эта ошибка: ОШИБКА в src / app / service / Coins.service.ts (34,22): ошибка TS2339: свойство «data» не существует для типа «Object».
Это потому, что вы не ввели объект данных. Попробуй так: .pipe(map((res: { data: any; metadata: any }) => res.data)) Любой надо конечно поменять на что-то более стабильное
ошибка TS2339: свойство «подписаться» не существует для типа «void».
Как насчет скриншота или фрагмента?
Не могли бы вы показать определение для
Coin, пожалуйста