Karl
Karl

Reputation: 111

Custom pagination using ReactJS

I have this project for pagination of json data received through an API. The problem is that my code somehow gives me a 'slice' error (it is not the case when using other API's, e.g. https://corona.lmao.ninja/v2/countries) <--- Works fine

Items.js:

import React from 'react';
import { ITEMS_PER_PAGE } from '../utils/constants';
import Data from './Data';

const Items = ({ items, page }) => {
  const startIndex = (page - 1) * ITEMS_PER_PAGE;
  const selectedItems = items.slice(startIndex, startIndex + ITEMS_PER_PAGE);
  return (
    <React.Fragment>
      {selectedItems.map(item => (
        <Data key={item.country} {...item} />
      ))}
    </React.Fragment>
  );
};

export default Items;

Data.js:

import React from 'react';

const Data = ({ Data }) => {
  const { high, low } = Data;
  return (
    <div class="data">
      <p>
        <strong>Test:</strong> {high} {low}
      </p>
      <hr />
    </div>
  );
};

export default Data;

Pagination.js:

import React from 'react';

const Pagination = ({ totalPages, handleClick, page }) => {
  const pages = [...Array(totalPages).keys()].map(number => number + 1);

  return (
    <div className="numbers">
      {pages.map(number => (
        <a
          key={number}
          href="/#"
          onClick={() => handleClick(number)}
          className={`${page === number && 'active'}`}
        >
          {number}
        </a>
      ))}
    </div>
  );
};

export default Pagination;

App.js:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Pagination from './components/Pagination';
import Items from './components/Items';
import { ITEMS_PER_PAGE } from './utils/constants';

const App = () => {
  const [items, setItems] = useState([]);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(0);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    setIsLoading(true);
    axios
      .get('https://min-api.cryptocompare.com/data/v2/histoday?fsym=BTC&tsym=USD&limit=10')
      .then(response => {
        const result = response.data;
        setItems(result);
        setTotalPages(Math.ceil(result.length / ITEMS_PER_PAGE));
        setIsLoading(false);
      });
  }, []);

  const handleClick = number => {
    setPage(number);
  };

  return (
    <div>
      <h1>Pagination Demo</h1>
      {isLoading ? (
        <div className="loading">Loading...</div>
      ) : (
        <React.Fragment>
          <Items items={items} page={page} />
          <Pagination
            totalPages={totalPages}
            handleClick={handleClick}
            page={page}
          />
        </React.Fragment>
      )}
    </div>
  );
};

export default App;

My problem seems to be something that am I missing with this other API: https://min-api.cryptocompare.com/data/v2/histoday?fsym=BTC&tsym=USD&limit=10

error: TypeError: items.slice is not a function in Items.js

Any help would be appreciated!

Upvotes: 0

Views: 452

Answers (1)

vuongvu
vuongvu

Reputation: 829

The response from the API has 2 nested Data keys, so it has to be like this:

const result = response.data;
setItems(result.Data.Data);

Data.js

import React from 'react';

const Data = ({ high, low }) => {

  return (
    <div class="data">
      <p>
        <strong>Test:</strong> {high} {low}
      </p>
      <hr />
    </div>
  );
};

export default Data;

demo: https://stackblitz.com/edit/react-arqaxj

Upvotes: 1

Related Questions