0
votes

I want to paginate the reults of an Api call. I am making an Api Call by using Axios like this

apiCall() {
const API = `http://www.omdbapi.com/`;
axios.get(API, {
        params: {
            apikey: process.env.REACT_APP_MOVIECALL_API_KEY,
            type: 'movie',
            s: 'superhero',
            page: this.state.pageCount
        }
    })
    .then(res => {
        const superheroes = res.data.Search
        const totalResults= parseInt(res.data.totalResults)
        this.setState({
            totalResults
        });
        this.setState({
            superheroes
        })
    })
    .catch((error) => {
        console.log(error);
    });
}

When the component is mounted the function called, as such

  componentDidMount() 
    { 
     this.apiCall();
    }

In the render function I map over each search result (in the api call the s param is the search option) and for each result I display a button, that when clicked displays the related info of that movie. The api by default displays 10 results per call but this particular search has 123 results in total. Now by updating the param page in the call which I've set to this.state.pageCount it displays 10 different movies relating to that page, at the moment I hardcode the pageCount inside the state to make sure it works and the corresponding page number shows the right list of 10 movies.

Now I would like to paginate the results by updating the page number, so when you click on next or the number 3/4/5 then the component loads the correct corresponding results, I've tried a couple of option relating to react but they somehow don't update the page number.

If someone could point me in the right direction or knows a simple solution, I am all ears.

the following code is the whole component, to get an idea of what I am trying to do.

What I have so far seems to be working, so what I am asking is for a simpler more elegant way of doing pagination for this particular situation.

export class MovieDetails extends Component {
  constructor(props){
    super(props)
    this.state = {
      superheroes: [],
      clicked: false,
      activeHero: {},
      pageCount: 11,
      totalResults: null,
      currentPage: 1
    }
    this.handleClick = this.handleClick.bind(this);
  }


  handleClick(hero) {
    const checkActive = this.state.activeHero.imdbID === hero.imdbID
    const activeHero = {...hero, active: !checkActive}
    this.setState({
      clicked: !this.state.clicked,
      activeHero
    })
  }    

  apiCall() {
    const API = `http://www.omdbapi.com/`;
    axios.get(API, {
            params: {
                apikey: process.env.REACT_APP_MOVIECALL_API_KEY,
                type: 'movie',
                s: 'superhero',
                page: this.state.pageCount
            }
        })
        .then(res => {
            const superheroes = res.data.Search
            const totalResults = parseInt(res.data.totalResults)
            this.setState({
              totalResults
            });
            this.setState({
                superheroes
            })
        })
        .catch((error) => {
            console.log(error);
        });
  }

  componentDidMount() {
    this.apiCall();
    }

    handlePageChange = (page, e) => {
      this.setState({
        currentPage: page
      });
      this.apiCall(this.setState({pageCount: page}))

    };


  render() {

    const {superheroes, currentPage } = this.state
    return (
        <div>
      {
        superheroes.map((hero, i) => 
            <div className="Results" key={i}>
            <button onClick={() => {this.handleClick(hero)}}> 
            <h1>{hero.Title}</h1>
            {
              this.state.clicked && this.state.activeHero.imdbID === hero.imdbID
                ? <ul>
                    {<div key={i}>
                    Movie Title: <h2> {hero.Title}</h2>
                      Year of Release: <h2>{hero.Year}</h2>
                      ID: <h2>{hero.imdbID}</h2>
                      <div><img className="Poster" alt="movieposter" src={hero.Poster}/></div>
                      </div>
              }
            </ul>
          : null
      }
      </button>
      </div>) 
   }
          <div className="Pagination"> 
          <Pagination
          total={this.state.totalResults}
          limit={10}
          pageCount={this.state.pageCount}
          currentPage={currentPage}
        >
          {({
            pages,
            currentPage,
            hasNextPage,
            hasPreviousPage,
            previousPage,
            nextPage,
            totalPages,
            getPageItemProps
          }) => (
            <div>
              <button
                {...getPageItemProps({
                  pageValue: 1,
                  onPageChange: this.handlePageChange
                })}
              >
                first
              </button>

              {hasPreviousPage && (
                <button
                  {...getPageItemProps({
                    pageValue: previousPage,
                    onPageChange: this.handlePageChange
                  })}
                >
                  {'<'}
                </button>
              )}

              {pages.map(page => {
                let activePage = null;
                if (currentPage === page) {
                  activePage = { backgroundColor: '#fdce09' };
                }
                return (
                  <button
                    {...getPageItemProps({
                      pageValue: page,
                      key: page,
                      style: activePage,
                      onPageChange: this.handlePageChange
                    })}
                  >
                    {page}
                  </button>
                );
              })}

              {hasNextPage && (
                <button
                  {...getPageItemProps({
                    pageValue: nextPage,
                    onPageChange: this.handlePageChange
                  })}
                >
                  {'>'}
                </button>
              )}

              <button
                {...getPageItemProps({
                  pageValue: totalPages,
                  onPageChange: this.handlePageChange
                })}
              >
                last
              </button>
            </div>
          )}
        </Pagination>
          </div>
      </div>

    );
  }
}
1

1 Answers

0
votes

In your axios.get function you are sending page: this.state.pageCount, however in your handlePageChange function you are setting state.currentPage which doesn't seem right to me.

I'm also a bit confused about the onPageChange event on <button />. Is this button a custom component you are importing (in which case it should be capatalised so that it's clear) or is it a HTML button? If it's a HTML button then you need to use the onClick event which will pass the event as and argument to the handlePageChange function. I'm guessing it's custom though from the props you're passing it so just worth checking that it's sending the page value through correctly.