Tequila
Tequila

Reputation: 256

Lopping over arrays in typescript

I can't seem to grasp over looping arrays/objects. I get stuck pretty often in them. Like here for example I cant iterate the data from the api, I am getting the trending is not a function error. Can somebody help me fix this, and give me some good direction to get better at looping

Interface

export interface Item {
    id: string;
    name: string;
    symbol: string;
    market_cap_rank: number;
    thumb: string;
    large: string;
    score: number;
}

export interface Coin {
    item: Item;
}

export interface ResponseObject{
    coins: Coin[];
   
}


Code

import React, { useEffect, useState} from 'react'
import axios from  'axios'
import { ResponseObject } from '../interfaces';
const TRENDING = 'https://api.coingecko.com/api/v3/search/trending'
const Home:React.FC= () => {
  
    const [trending, setTrending ] = useState<ResponseObject[]>([])
    useEffect(()=>{
        axios
        .get<ResponseObject[]>(TRENDING)
        .then((response) => 
        {setTrending(response.data); 
        console.log(response) })
        .catch(err =>
        { console.log(err); })
    },[])

    return (
        <div>  
           {trending.map(trend =>
           (<div key={trend.item.id}>{trend.item.name}</div>))}
        </div>
    )
}

export default Home

Api

{
   "coins":[
      {
         "item":{
            "id":"superfarm",
            "name":"SuperFarm",
            "symbol":"SUPER",
            "market_cap_rank":235,
            "thumb":"https://assets.coingecko.com/coins/images/14040/thumb/6YPdWn6.png?1613975899",
            "large":"https://assets.coingecko.com/coins/images/14040/large/6YPdWn6.png?1613975899",
            "score":0
         }
      },
      {...}
   ],
   "exchanges":[]
}

Upvotes: 0

Views: 68

Answers (2)

moonwave99
moonwave99

Reputation: 22810

The problem has nothing to do with looping.

You are calling setTrending with something that is not an array. that's why you are getting trending.map is not a function.

Your API is not directly returning an array, but an objet with two keys, each one holding an array.

In your case, you have to call setTrending(response.data.coins).

EDIT: you should also fix your ResponseObject usage:

const [trending, setTrending ] = useState<Coin[]>([]);

useEffect(()=> {
    axios
      .get<ResponseObject>(TRENDING)
      .then((response) =>  {
        setTrending(response.data.coins); 
    })
    .catch(err => console.log(err));
},[]);

Upvotes: 1

Sifat Moonjerin
Sifat Moonjerin

Reputation: 308

I guess you have probably set an object as trending instead of an array. response.data should return an object which will be similar to your API.

// response.data should return this object.
{
   "coins":[
      {
         "item":{
            "id":"superfarm",
            "name":"SuperFarm",
            "symbol":"SUPER",
            "market_cap_rank":235,
            "thumb":"https://assets.coingecko.com/coins/images/14040/thumb/6YPdWn6.png?1613975899",
            "large":"https://assets.coingecko.com/coins/images/14040/large/6YPdWn6.png?1613975899",
            "score":0
         }
      },
      {...}
   ],
   "exchanges":[]
}

You should set response.data.coins as trending which will return an array.

[
      {
         "item":{
            "id":"superfarm",
            "name":"SuperFarm",
            "symbol":"SUPER",
            "market_cap_rank":235,
            "thumb":"https://assets.coingecko.com/coins/images/14040/thumb/6YPdWn6.png?1613975899",
            "large":"https://assets.coingecko.com/coins/images/14040/large/6YPdWn6.png?1613975899",
            "score":0
         }
      },
      {...}
]

Upvotes: 1

Related Questions