Rewrote most of how api calls are made when searching for a movie and how the returning data is handled. We now have finer handling of status response from the original api call aswell as if any of the functions hit a error e.g. not hitting the server, than we have our own errors thrown. Also updated the page incrementers to updated the last api call with a higher or lower number.
This commit is contained in:
		@@ -4,6 +4,7 @@ import MovieObject from './MovieObject.jsx';
 | 
			
		||||
 | 
			
		||||
// StyleComponents
 | 
			
		||||
import searchStyle from './styles/searchRequestStyle.jsx';
 | 
			
		||||
import movieStyle from './styles/movieObjectStyle.jsx'
 | 
			
		||||
 | 
			
		||||
import URI from 'urijs';
 | 
			
		||||
 | 
			
		||||
@@ -13,23 +14,25 @@ class SearchRequest extends React.Component {
 | 
			
		||||
    super(props)
 | 
			
		||||
    // Constructor with states holding the search query and the element of reponse.
 | 
			
		||||
    this.state = {
 | 
			
		||||
      lastApiCallURI: '',
 | 
			
		||||
      searchQuery: '',
 | 
			
		||||
      responseMovieList: null,
 | 
			
		||||
      movieFilter: true,
 | 
			
		||||
      showFilter: false,
 | 
			
		||||
      discoverType: '',
 | 
			
		||||
      page: 1
 | 
			
		||||
      page: 1,
 | 
			
		||||
      resultHeader: ''
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.allowedDiscoverTypes = [
 | 
			
		||||
    this.allowedListTypes = [
 | 
			
		||||
        'discover', 'popular', 'nowplaying', 'upcoming'
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    this.baseUrl = 'https://apollo.kevinmidboe.com/api/v1/tmdb';
 | 
			
		||||
    this.baseUrl = 'https://apollo.kevinmidboe.com/api/v1/tmdb/';
 | 
			
		||||
    // this.baseUrl = 'http://localhost:31459/api/v1/tmdb/';
 | 
			
		||||
 | 
			
		||||
    this.URLs = {
 | 
			
		||||
      request: 'https://apollo.kevinmidboe.com/api/v1/plex/request?page='+this.state.page+'&query=',
 | 
			
		||||
      searchRequest: 'https://apollo.kevinmidboe.com/api/v1/plex/request',
 | 
			
		||||
      // request: 'http://localhost:31459/api/v1/plex/request?page='+this.state.page+'&query=',
 | 
			
		||||
      upcoming: 'https://apollo.kevinmidboe.com/api/v1/tmdb/upcoming',
 | 
			
		||||
      // upcoming: 'http://localhost:31459/api/v1/tmdb/upcoming',
 | 
			
		||||
@@ -45,26 +48,125 @@ class SearchRequest extends React.Component {
 | 
			
		||||
    this.fetchDiscover('upcoming');
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Handles all errors of the response of a fetch call
 | 
			
		||||
  handleErrors(response) {
 | 
			
		||||
    if (!response.ok) {
 | 
			
		||||
      throw Error(response.status);
 | 
			
		||||
    // Handles all errors of the response of a fetch call
 | 
			
		||||
    handleErrors(response) {
 | 
			
		||||
        if (!response.ok)
 | 
			
		||||
            throw Error(response.status);
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
    return response;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    handleQueryError(response) {
 | 
			
		||||
        if (!response.ok) {
 | 
			
		||||
            if (response.status === 404) {
 | 
			
		||||
                this.setState({
 | 
			
		||||
                    responseMovieList: <h1>Nothing found for search query: { this.findQueryInURI(uri) }</h1>
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
            console.log(error);
 | 
			
		||||
        }
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Unpacks the query value of a uri
 | 
			
		||||
    findQueryValueInURI(uri) {
 | 
			
		||||
        let uriSearchValues = uri.query(true);
 | 
			
		||||
        let queryValue = uriSearchValues['query']
 | 
			
		||||
 | 
			
		||||
        return queryValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    resetPageNumber() {
 | 
			
		||||
        this.state.page = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Test this by calling missing endpoint or 404 query and see what code
 | 
			
		||||
    // and filter the error message based on the code.
 | 
			
		||||
    // Calls a uri and returns the response as json
 | 
			
		||||
    callURI(uri) {
 | 
			
		||||
        return fetch(uri)
 | 
			
		||||
        .then(response => { return response })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
            throw Error('Something went wrong while fetching URI.');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Saves the input string as a h1 element in responseMovieList state
 | 
			
		||||
    fillResponseMovieListWithError(msg) {
 | 
			
		||||
        this.setState({
 | 
			
		||||
            responseMovieList: <h1>{ msg }</h1>
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Here we first call api for a search with the input uri, handle any errors
 | 
			
		||||
    // and fill the reponseData from api into the state of reponseMovieList as movieObjects
 | 
			
		||||
    callSearchFillMovieList(uri) {
 | 
			
		||||
        Promise.resolve()
 | 
			
		||||
        .then(() => this.callURI(uri))
 | 
			
		||||
        .then(response => {
 | 
			
		||||
            // If we get a error code for the request
 | 
			
		||||
            if (!response.ok) {
 | 
			
		||||
                if (response.status === 404) {
 | 
			
		||||
                    let errorMsg = 'Nothing found for the search query: ' + this.findQueryValueInURI(uri);
 | 
			
		||||
                    this.fillResponseMovieListWithError(errorMsg)
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    let errorMsg = 'Error fetching query from server ' + this.response.status;
 | 
			
		||||
                    this.fillResponseMovieListWithError(errorMsg) 
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Convert to json and update the state of responseMovieList with the results of the api call
 | 
			
		||||
            // mapped as a movieObject.
 | 
			
		||||
            response.json()
 | 
			
		||||
            .then(responseData => {
 | 
			
		||||
                this.setState({
 | 
			
		||||
                    responseMovieList: responseData.results.map(searchResultItem => this.createMovieObjects(searchResultItem)),
 | 
			
		||||
                    lastApiCallURI: uri  // Save the value of the last sucessfull api call
 | 
			
		||||
                })
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        .catch(() => {
 | 
			
		||||
            throw Error('Something went wrong when fetching query.')
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    searchSeasonedRequest() {
 | 
			
		||||
        // Build uri with the url for searching requests
 | 
			
		||||
        var uri = new URI(this.URLs.searchRequest);
 | 
			
		||||
        // Add input of search query and page count to the uri payload
 | 
			
		||||
        uri = uri.search({ 'query': this.state.searchQuery, 'page': this.state.page });
 | 
			
		||||
        
 | 
			
		||||
        if (this.state.showFilter)
 | 
			
		||||
            uri = uri.addSearch('type', 'show');
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Send uri to call and fill the response list with movie/show objects
 | 
			
		||||
        this.callSearchFillMovieList(uri);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  fetchDiscover(queryDiscoverType) {
 | 
			
		||||
    if (this.allowedDiscoverTypes.indexOf(queryDiscoverType) === -1)
 | 
			
		||||
    if (this.allowedListTypes.indexOf(queryDiscoverType) === -1)
 | 
			
		||||
        throw Error('Invalid discover type: ' + queryDiscoverType);
 | 
			
		||||
 | 
			
		||||
    // Captialize the first letter of and save the discoverQueryType to resultHeader state. 
 | 
			
		||||
    this.state.resultHeader = queryDiscoverType.toLowerCase().replace(/\b[a-z]/g, function(letter) {
 | 
			
		||||
        return letter.toUpperCase();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var uri = new URI(this.baseUrl);
 | 
			
		||||
    uri.segment(queryDiscoverType)
 | 
			
		||||
    uri = uri.setSearch('page', this.state.page);
 | 
			
		||||
    if (this.state.showFilter)
 | 
			
		||||
        uri = uri.addSearch('type', 'show');
 | 
			
		||||
 | 
			
		||||
    console.log(uri)
 | 
			
		||||
 | 
			
		||||
    this.state.lastApiCallURI = uri;
 | 
			
		||||
 | 
			
		||||
    this.setState({
 | 
			
		||||
        responseMovieList: 'Loading...'
 | 
			
		||||
@@ -96,11 +198,15 @@ class SearchRequest extends React.Component {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  fetchQuery() {
 | 
			
		||||
    let url = this.URLs.request + this.state.searchQuery
 | 
			
		||||
    let url = this.URLs.request + this.state.searchQuery;
 | 
			
		||||
    if (this.state.showFilter) {
 | 
			
		||||
      url = url + '&type=tv'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.state.apiQuery = url;
 | 
			
		||||
    console.log(this.state.apiQuery.toString());
 | 
			
		||||
    this.state.resultHeader = "Results for: " + this.state.searchQuery + "";
 | 
			
		||||
 | 
			
		||||
  fetch(url)
 | 
			
		||||
    // Check if the response is ok
 | 
			
		||||
    .then(response => this.handleErrors(response))
 | 
			
		||||
@@ -135,7 +241,10 @@ class SearchRequest extends React.Component {
 | 
			
		||||
  // For checking if the enter key was pressed in the search field.
 | 
			
		||||
  _handleQueryKeyPress(e) {
 | 
			
		||||
    if (e.key === 'Enter') {
 | 
			
		||||
      this.fetchQuery();
 | 
			
		||||
        // this.fetchQuery();
 | 
			
		||||
        // Reset page number for a new search
 | 
			
		||||
        this.resetPageNumber();
 | 
			
		||||
        this.searchSeasonedRequest();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -161,21 +270,39 @@ class SearchRequest extends React.Component {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pageBackwards() {
 | 
			
		||||
    if (this.state.page > 1) {
 | 
			
		||||
      console.log('backwards');
 | 
			
		||||
      this.state.page--;
 | 
			
		||||
      this.getUpcoming();
 | 
			
		||||
    }
 | 
			
		||||
    console.log(this.state.page)
 | 
			
		||||
  }
 | 
			
		||||
    pageBackwards() {
 | 
			
		||||
        if (this.state.page > 1) {
 | 
			
		||||
            let pageNumber = this.state.page - 1;
 | 
			
		||||
            let uri = this.state.lastApiCallURI;
 | 
			
		||||
            
 | 
			
		||||
  pageForwards() {
 | 
			
		||||
    this.state.page++;
 | 
			
		||||
    this.getUpcoming();
 | 
			
		||||
    console.log('forwards');
 | 
			
		||||
    console.log(this.state.page)
 | 
			
		||||
  }
 | 
			
		||||
            // Augment the page number of the uri with a callback
 | 
			
		||||
            uri.search(function(data) {
 | 
			
		||||
                data.page = pageNumber;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Call the api with the new uri
 | 
			
		||||
            this.callSearchFillMovieList(uri);
 | 
			
		||||
            // Update state of our page number after the call is done
 | 
			
		||||
            this.state.page = pageNumber;
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO need to get total page number and save in a state to not overflow
 | 
			
		||||
    pageForwards() {
 | 
			
		||||
        // Wrap this in the check
 | 
			
		||||
        let pageNumber = this.state.page + 1;
 | 
			
		||||
        let uri = this.state.lastApiCallURI;
 | 
			
		||||
        
 | 
			
		||||
        // Augment the page number of the uri with a callback
 | 
			
		||||
        uri.search(function(data) {
 | 
			
		||||
            data.page = pageNumber;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Call the api with the new uri
 | 
			
		||||
        this.callSearchFillMovieList(uri);
 | 
			
		||||
        // Update state of our page number after the call is done
 | 
			
		||||
        this.state.page = pageNumber;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  render(){
 | 
			
		||||
@@ -186,40 +313,44 @@ class SearchRequest extends React.Component {
 | 
			
		||||
        <button onClick={() => {this.fetchDiscover('nowplaying')}}>Nowplaying</button>
 | 
			
		||||
        <button onClick={() => {this.fetchDiscover('upcoming')}}>Upcoming</button>
 | 
			
		||||
 | 
			
		||||
          <div className='backgroundHeader' style={searchStyle.backgroundHeader}>
 | 
			
		||||
            <div className='pageTitle' style={searchStyle.pageTitle}>
 | 
			
		||||
              <span style={searchStyle.pageTitleSpan}>Request new movies or tv shows</span>
 | 
			
		||||
            </div>
 | 
			
		||||
        <div className='backgroundHeader' style={searchStyle.backgroundHeader}>
 | 
			
		||||
          <div className='pageTitle' style={searchStyle.pageTitle}>
 | 
			
		||||
            <span style={searchStyle.pageTitleSpan}>Request new movies or tv shows</span>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
            <div className='box' style={searchStyle.box}>
 | 
			
		||||
              <div style={searchStyle.container}>
 | 
			
		||||
                <span style={searchStyle.searchIcon}><i className="fa fa-search"></i></span>
 | 
			
		||||
          <div className='box' style={searchStyle.box}>
 | 
			
		||||
            <div style={searchStyle.container}>
 | 
			
		||||
              <span style={searchStyle.searchIcon}><i className="fa fa-search"></i></span>
 | 
			
		||||
 | 
			
		||||
                <input style={searchStyle.searchBar} type="text" id="search" placeholder="Search for new content..." 
 | 
			
		||||
                  onKeyPress={(event) => this._handleQueryKeyPress(event)}
 | 
			
		||||
                  onChange={event => this.updateQueryState(event)}
 | 
			
		||||
                  value={this.state.searchQuery}/>
 | 
			
		||||
              <input style={searchStyle.searchBar} type="text" id="search" placeholder="Search for new content..." 
 | 
			
		||||
                onKeyPress={(event) => this._handleQueryKeyPress(event)}
 | 
			
		||||
                onChange={event => this.updateQueryState(event)}
 | 
			
		||||
                value={this.state.searchQuery}/>
 | 
			
		||||
 | 
			
		||||
                <span style={searchStyle.searchFilter}
 | 
			
		||||
                  className="search_category hvrUnderlineFromCenter" 
 | 
			
		||||
                  onClick={() => {this.toggleFilter('movies')}}
 | 
			
		||||
                  id="category_active">Movies</span>
 | 
			
		||||
                <span style={searchStyle.searchFilter} 
 | 
			
		||||
                  className="search_category hvrUnderlineFromCenter" 
 | 
			
		||||
                  onClick={() => {this.toggleFilter('shows')}}
 | 
			
		||||
                  id="category_inactive">TV Shows</span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <span style={searchStyle.searchFilter}
 | 
			
		||||
                className="search_category hvrUnderlineFromCenter" 
 | 
			
		||||
                onClick={() => {this.toggleFilter('movies')}}
 | 
			
		||||
                id="category_active">Movies</span>
 | 
			
		||||
              <span style={searchStyle.searchFilter} 
 | 
			
		||||
                className="search_category hvrUnderlineFromCenter" 
 | 
			
		||||
                onClick={() => {this.toggleFilter('shows')}}
 | 
			
		||||
                id="category_inactive">TV Shows</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
          <div id='requestMovieList' ref='requestMovieList' style={searchStyle.requestWrapper}>
 | 
			
		||||
            {this.state.responseMovieList}     
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <button onClick={() => {this.pageBackwards()}}>Back</button>
 | 
			
		||||
            <button onClick={() => {this.pageForwards()}}>Forward</button>
 | 
			
		||||
          </div>
 | 
			
		||||
      </div>
 | 
			
		||||
        <div id='requestMovieList' ref='requestMovieList' style={searchStyle.requestWrapper}>
 | 
			
		||||
          
 | 
			
		||||
          <h1 style={searchStyle.resultHeader}>{this.state.resultHeader}</h1>
 | 
			
		||||
          
 | 
			
		||||
          {this.state.responseMovieList}     
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <div style={searchStyle.pageNavigationBar}>
 | 
			
		||||
          <button onClick={() => {this.pageBackwards()}} style={searchStyle.pageNavigationButton}>Back</button>
 | 
			
		||||
          <button onClick={() => {this.pageForwards()}} style={searchStyle.pageNavigationButton}>Forward</button>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user