显示来自API搜索调用的数据(来自TMDB)

时间:2020-05-04 20:54:39

标签: javascript reactjs api

我当时从https://www.youtube.com/watch?v=22SAhH5JxYk查找搜索功能,并尝试将其应用到搜索URL,这是对TMDB数据库的api调用,具有深层分支响应。 搜索看起来像这样: { } { "page": 1, "total_results": 141, "total_pages": 8, "results": [ { "vote_count": 14162, "popularity": 40.812, "id": 272, "video": false, "media_type": "movie", "vote_average": 7.7, "title": "Batman Begins", "release_date": "2005-06-10", "original_language": "en", "original_title": "Batman Begins", "genre_ids": [ 28, 80, 18 ], "backdrop_path": "/lh5lbisD4oDbEKgUxoRaZU8HVrk.jpg", "adult": false, "overview": "Driven by tragedy, billionaire Bruce Wayne dedicates his life to uncovering and defeating the corruption that plagues his home, Gotham City. Unable to work within the system, he instead creates a new identity, a symbol of fear for the criminal underworld - The Batman.", "poster_path": "/aGdng8Ic4ONpcepU3bVXPSLmNd3.jpg" }, { "original_name": "Batman", "genre_ids": [ 35, 10759, 10765 ], "media_type": "tv", "name": "Batman", "popularity": 24.871, "origin_country": [ "US" ], "vote_count": 153, "first_air_date": "1966-01-12", "backdrop_path": "/gpJZiTvklr5JN0mzpQwl99peQD7.jpg", "original_language": "en", "id": 2287, "vote_average": 7.1, "overview": "Wealthy entrepreneur Bruce Wayne and his ward Dick Grayson lead a double life: they are actually crime fighting duo Batman and Robin. A secret Batpole in the Wayne mansion leads to the Batcave, where Police Commissioner Gordon often calls with the latest emergency threatening Gotham City. Racing the the scene of the crime in the Batmobile, Batman and Robin must (with the help of their trusty Bat-utility-belt) thwart the efforts of a variety of master criminals, including The Riddler, The Joker, Catwoman, and The Penguin.", "poster_path": "/1ZEJuuDh0Zpi5ELM3Zev0GBhQ3R.jpg" }, { "poster_path": "/xVaHD9sgzwE129UcdhMtwyhndYj.jpg", "popularity": 21.393, "vote_count": 4657, "video": false, "media_type": "movie", "id": 268, "adult": false, "backdrop_path": "/rBN6GPKUDZ6ZKAQiEZegZ0DZb6V.jpg", "original_language": "en", "original_title": "Batman", "genre_ids": [ 28, 14 ], "title": "Batman", "vote_average": 7.2, "overview": "The Dark Knight of Gotham City begins his war on crime with his first major enemy being the clownishly homicidal Joker, who has seized control of Gotham's underworld.", "release_date": "1989-06-23" }, { "original_name": "The Batman", "genre_ids": [ 16, 9648, 10759, 10765 ], "media_type": "tv", "name": "The Batman", "popularity": 27.069, "origin_country": [ "US" ], "vote_count": 74, "first_air_date": "2004-09-11", "backdrop_path": null, "original_language": "en", "id": 2022, "vote_average": 7.5, "overview": "The Batman is an American animated television series produced by Warner Bros. Animation based on the DC Comics superhero Batman. It ran from September 11, 2004 to March 22, 2008, on the Saturday morning television block Kids' WB.\n\nAlthough the series borrows many elements from previous Batman storylines, it does not follow the continuity set by the comic books, the film series, nor that of Batman: The Animated Series and its spin-offs. The character designs were provided by Jackie Chan Adventures artist Jeff Matsuda; he also directed the ending. The series won six Daytime Emmy Awards.", "poster_path": "/qTYUK6BHYHXEuMiVI6KjZOkm2w4.jpg" }, { "poster_path": "/bsg0mrxUKyJoL4oSGP5mlhEsqp.jpg", "popularity": 22.591, "vote_count": 3201, "video": false, "media_type": "movie", "id": 415, "adult": false, "backdrop_path": "/tgPFZxhDuxWd4VXYaz8eAUznGTF.jpg", "original_language": "en", "original_title": "Batman & Robin", "genre_ids": [ 28, 35, 14, 878 ], "title": "Batman & Robin", "vote_average": 4.3, "overview": "Along with crime-fighting partner Robin and new recruit Batgirl, Batman battles the dual threat of frosty genius Mr. Freeze and homicidal horticulturalist Poison Ivy. Freeze plans to put Gotham City on ice, while Ivy tries to drive a wedge between the dynamic duo.", "release_date": "1997-06-20" },

import './stylesheetSearch.css'
import axios from 'axios';
import Loader from './loader.gif'
import PageNavigation from "./PageNavigation";
import Table from "@material-ui/core/Table";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import TableCell from "@material-ui/core/TableCell";
import TableBody from "@material-ui/core/TableBody";
import DeleteIcon from "@material-ui/icons/Delete";
class Search extends Component{
    constructor(props) {
        super(props);
        this.state={
            query:'',
            results:{},
            loading: false,
            message:'',
            totalResults: 0,
            totalPages: 0,
            currentPageNo: 0,


        }
        this.cancel = '';
    }


    //////
    handleOnInputChange = ( event ) => {
        const query = event.target.value;
        if ( ! query ) {
            this.setState( { query, results: {}, message: '', totalPages: 0, totalResults: 0 } );
        } else {
            this.setState( { query, loading: true, message: '' }, () => {
                this.fetchSearchResults( 1, query );
            } );
        }
    };

    fetchSearchResults = ( updatedPageNo = '', query ) => {
        const pageNumber = updatedPageNo ? `&page=${updatedPageNo}` : '';
        const searchUrl = `https://api.themoviedb.org/3/search/multi?api_key=(input api key)&query=${query}${pageNumber}`;
////we wanr to search only when we finished typing
        //we use a cancel token to cancel the request before we finish typing
        if( this.cancel ) {
            this.cancel.cancel();
        }

        this.cancel = axios.CancelToken.source();

        axios.get( searchUrl, {
            cancelToken: this.cancel.token
        } )
            .then( res => {
                const total = res.data.total;
                console.warn(res.data);
                const totalPagesCount = this.getPageCount( total, 20 );
                const resultNotFoundMsg = ! res.data.hits.length
                    ? 'There are no more search results. Please try a new search'
                    : '';
                this.setState( {
                    results: res.data.hits,
                    message: resultNotFoundMsg,
                    totalResults: total,
                    totalPages: totalPagesCount,
                    currentPageNo: updatedPageNo,
                    loading: false
                } )
            } )
            .catch( error => {
                if ( axios.isCancel(error) || error ) {
                    this.setState({
                        loading: false,
                        message: 'Failed to fetch the data. Please check network'
                    })
                }
            } )
    };
///methid to loop through array of results

    renderSearchResults = () => {
        const { results } = this.state;

                    if ( Object.keys( results ).length && results.length ) {
                        return (
                            <div className="results-container">
                                {this.state.results.map(result => {
                                    return (
                                        <h3 key={result.id}  className="result-item">
                                            <h6 className="image-username">{result.title}</h6>

                                        </h3>
                                    )
                                })}


                            </div>
                        )
                    }
    }

    getPageCount = ( total, denominator ) => {
        const divisible = 0 === total % denominator;
        const valueToBeAdded = divisible ? 0 : 1;
        return Math.floor( total/denominator ) + valueToBeAdded;
    };
    handlePageClick = ( type ) => {
       // event.preventDefault();
        const updatePageNo = 'prev' === type
            ? this.state.currentPageNo - 1
            : this.state.currentPageNo + 1;

        if( ! this.state.loading  ) {
            this.setState( { loading: true, message: '' }, () => {
                this.fetchSearchResults( updatePageNo, this.state.query );
            } );
        }
    };

    render()
    {
        const { query, loading, message, currentPageNo, totalPages } = this.state;

        const showPrevLink = 1 < currentPageNo;
        const showNextLink = totalPages > currentPageNo;
        return(

          <div className="container">
              {/*Heading*/}
              <h2 className="heading">Live Search for movies</h2>
              {/*Search Input*/}
              <label className="search-labe" htmlFor="search-input">
                  <input type="text"  value={query} id="search-input" placeholder="Search...." name="query"
                      onChange ={this.handleOnInputChange}
                  />
                  <i className="fas fa-search" aria-hidden="true"></i>
              </label>


              {/*   Error Message*/}
              {message && <p className="message">{ message }</p>}

              {/*   Loader*/}
              <img src={ Loader } className={`search-loading ${ loading ? 'show' : 'hide' }`} alt="loader"/>
              {/*Navigation*/}
              <PageNavigation
                  loading={loading}
                  showPrevLink={showPrevLink}
                  showNextLink={showNextLink}
                  handlePrevClick={ () => this.handlePageClick('prev')}
                  handleNextClick={ () => this.handlePageClick('next' )}
              />

              {/*   Result*/}
              { this.renderSearchResults() }


              {/*Navigation*/}
              <PageNavigation
                  loading={loading}
                  showPrevLink={showPrevLink}
                  showNextLink={showNextLink}
                  handlePrevClick={ () => this.handlePageClick('prev')}
                  handleNextClick={ () => this.handlePageClick('next' )}
              />

          </div>
        );
    }


}
export  default Search;

我可以看到在控制台中获取了数据,因为我的数据没有用于预览图像的url(如果没有我从2个对象中创建一个),则无法像视频中那样输入PreviewUrl。 我以其他方式查找了内容,甚至只放了电影的标题,但是显示的最终结果是“没有搜索结果”,并且两边都没有错误。

我不知道如何从api调用中输出数据。

谢谢!

1 个答案:

答案 0 :(得分:0)

我知道了。 api调用的元素与我在其上进行映射的元素不同(因为我需要更深入地了解元素)。