Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

C#

Kyle Jensen
PLUS
Kyle Jensen
Courses Plus Student 6,293 Points

(de)serialization on TMdb api

For anyone viewing this in the future. See @stevenParkers comment at the bottom for the outcome

I'm working on a project for the (de)serialization section. My goal is to create a complete app using the TMdb API. I'm working through each problem one-by-one and I cannot seem to figure this one out. Currently, I'm able to get a list of movies by searching the title, or by genre. Each request returns a list in descending order based on popularity and the result is 1 page of 20 items. I've been able to change pages, but, if the requested search only has one page and I request another page it will just return an empty list(blank output). I want to avoid another request to the API if there is only one page and with the initial request I want to print out the total number of pages that can be viewed. That being said - I have been unable to access the value of total_pages. The only result I get is 0. What am I missing/doing wrong? Below I've added two classes and the JSON from the API documentation. You'll note at the bottom of the JSON is where the total_pages property is located. You can see my latest attempt to check the pages before incrementing and I've also tried printing the value in different ways to the console, to no avail.

link to documentation: https://developers.themoviedb.org/3/search/search-movies

GetListings.cs

// Genre ID search path = https://api.themoviedb.org/3/genre/12/movies?api_key=7cc33ddda390c1e661b0c6e87e0e5cd0&language=en-US&include_adult=false&sort_by=created_at.asc
        //Movie search path = https://api.themoviedb.org/3/search/movie?api_key=7cc33ddda390c1e661b0c6e87e0e5cd0&language=en-US&query=

        private string _tmdbBaseUrl = "https://api.themoviedb.org/3/";
        private string _searchMovies = "search/movie";
        private string _apiKey = "........................";
        private string _language = "language=en-US";
        public int _page { get; private set; } = 1;
        public int _genre { get; private set; }
        private List<MovieSearchResult> _results = new List<MovieSearchResult>();
        public int _pageCount { get; set; }//TODO: fix this


        public void PageNextOrBack(string choice) {
            var movieSearch = new MovieSearch();
            _pageCount = movieSearch.Pages;
            //if(choice == "next") {
            //    _page++;
            //}
            if (choice == "next" && _page < _pageCount) {
                _page ++;
            }
            if (choice == "back" && _page > 1) {
                _page--;
            }
        }

        public List<MovieSearchResult> GetMovies(string typeOfSearch, string query) {
            byte[] searchResults = SearchByMovieOrGenre(typeOfSearch, query);
            var serializer = new JsonSerializer();
            using (var stream = new MemoryStream(searchResults))
            using (var reader = new StreamReader(stream))
            using (var jsonReader = new JsonTextReader(reader)) {
                _results = serializer.Deserialize<MovieSearch>(jsonReader).Results;
            }
            return _results;
        }

        private byte[] SearchByMovieOrGenre(string typeOfSearch, string query) {
            byte[] searchResults = null;
            var webClient = new WebClient();
            if (typeOfSearch == "movie") {
                searchResults = webClient.DownloadData(string.Format($"{_tmdbBaseUrl}{_searchMovies}" +
                                                                     $"?api_key={_apiKey}&{_language}&query={query}&page={_page}"));
            }
            if (typeOfSearch == "genre") {
                query = _genre.ToString();
                searchResults = webClient.DownloadData(string.Format($"{_tmdbBaseUrl}genre/{query}/movies" +
                                                                 $"?api_key={_apiKey}&{_language}&include_adult=false&sort_by=created_at.asc"));
            }
            return searchResults;
        }

        public int GetGenreId(string genreType) {
            var genres = DeserializeGenres();
            foreach (var genre in genres) {
                if(genre.GenreType.ToLower().Trim() == genreType) {
                    _genre = genre.Id;
                    return _genre;
                }
            }
            return -1;
        }

        // used to deserialize genre.Json
            public static List<Genre> DeserializeGenres() {
            GetListings listings = new GetListings();
            string currDirectory = Directory.GetCurrentDirectory();
            DirectoryInfo directory = new DirectoryInfo(currDirectory);
            var fileName = Path.Combine(directory.FullName, "genre.Json");
            var genres = new List<Genre>();
            var serializer = new JsonSerializer();
            using (var reader = new StreamReader(fileName))
            using (var jsonReader = new JsonTextReader(reader)) {
                genres = serializer.Deserialize<List<Genre>>(jsonReader);
            }
            return genres;
        }

MovieSearchResults.cs

    public class MovieSearch {
        public int page { get; set; }
        [JsonProperty(PropertyName = "results")]
        public List<MovieSearchResult> Results { get; set; }
        public int total_results { get; set; }
        [JsonProperty(PropertyName = "total_pages")]
        public int Pages { get; set; }
    }

    public class MovieSearchResult {
        public string poster_path { get; set; }
        public bool adult { get; set; }
        [JsonProperty(PropertyName = "overview")]
        public string Overview { get; set; }
        public string release_date { get; set; }
        [JsonProperty(PropertyName = "genre_ids")]
        public int?[] GenreId { get; set; }
        public int id { get; set; }
        public string original_title { get; set; }
        public string original_language { get; set; }
        [JsonProperty(PropertyName = "title")]
        public string Title { get; set; }
        public string backdrop_path { get; set; }
        public float popularity { get; set; }
        public int vote_count { get; set; }
        public bool video { get; set; }
        [JsonProperty(PropertyName = "vote_average")]
        public float Rating { get; set; }
    }

JSON from documentation NOTE: its been chopped for size but has all the properties

{
"page": 1,
"results": [
    {
    "poster_path": "/l1R3ATerm8joOYXBl2QXx8ORzfw.jpg",
    "adult": false,
    "overview": "Film about an unemployed, socially handicapped bachelor who 
    lives in a very small world. For his birthday, his mother gives him a 
    young dog. The touching pup brings about a pleasant change in his lonely 
    life. But the growing up of the small dog forces him to make a radical 
    choice.",
    "release_date": "2002-09-23",
    "genre_ids": [
      18
    ],
    "id": 353026,
    "original_title": "Bob",
    "original_language": "nl",
    "title": "Bob",
    "backdrop_path": null,
    "popularity": 1.000396,
    "vote_count": 0,
    "video": false,
    "vote_average": 0
  },
  {
    "poster_path": "/lOc18fcPLemZBQt8u6VfFkylKdn.jpg",
    "adult": false,
    "overview": "Who says a hamster can't travel the world chasing down his 
     lady-love?",
    "release_date": "2011-06-30",
    "genre_ids": [],
    "id": 390984,
    "original_title": "Bob",
    "original_language": "en",
    "title": "Bob",
    "backdrop_path": null,
    "popularity": 1.001,
    "vote_count": 1,
    "video": false,
    "vote_average": 6
  },
  {
    "poster_path": "/aCvXgFNmP2G9w2VMsId7XVTrXx4.jpg",
    "adult": false,
    "overview": "In this second film revolving around the character Bølle 
     Bob, the town mayor and Miss Friis, the stuck-up headmistress, plan to 
     raze Lilleby School to the ground. And it¿s up to Bølle Bob, the class 
     clown, to take charge. Aided by the aging rock musician Valde, Bølle 
     Bob and all his friends put on a musical to recruit new students, so 
     their endangered school can survive. But the mayor and Miss Friis soon 
     reach into their bag of dirty tricks.",
    "release_date": "2010-08-01",
    "genre_ids": [
      10751
    ],
    "id": 56644,
    "original_title": "Bølle Bob: Alle tiders helt",
    "original_language": "da",
    "title": "Bob Bob Trouble Boy",
    "backdrop_path": "/neR4H24POvoQN9e28vP6XqqYDVI.jpg",
    "popularity": 1.002439,
    "vote_count": 1,
    "video": false,
    "vote_average": 6.5
  },
  {
    "poster_path": "/sMAMFFCGf07G5Cuo0WrlIFRH7o8.jpg",
    "adult": false,
    "overview": "Independent filmmaker Caveh Zahedi meets his childhood 
     idol.",
    "release_date": "2016-01-24",
    "genre_ids": [
      16,
      35
    ],
    "id": 379386,
    "original_title": "Bob Dylan Hates Me",
    "original_language": "en",
    "title": "Bob Dylan Hates Me",
    "backdrop_path": null,
    "popularity": 1.011612,
    "vote_count": 1,
    "video": false,
    "vote_average": 7
  }
  ],
"total_results": 540,
"total_pages": 27
}

1 Answer

Steven Parker
Steven Parker
231,108 Points

I don't see where you're reading the page count from the query results.

The only place where I see _pageCount being set, or a reference to Pages is in the first lines of PageNextOrBack:

            var movieSearch = new MovieSearch();
            _pageCount = movieSearch.Pages;

Since movieSearch is a newly created object instance, then _pageCount would naturally be 0 at this point. Did you intend to deserialize it from the search results?

Kyle Jensen
Kyle Jensen
Courses Plus Student 6,293 Points

Steven Parker Yeah, I tried to set _pageCount one of the times in GetMovies() but I don't think I was doing it right there either. I don't recall exactly how I wrote it, but the compiler threw an error once I made a call to it in the console - even though it would compile and run the first part of the application. Another way I tried was to get it from a method added to the MovieSearch class, but of course, that would also be zero, but I tried it anyways just to make sure. I sat and tried to work out how I could go about it in every way I could think before posting. The only other way I could think was to write the following code in the MovieSearchResults class. But that just seemed like a bad idea because I'd just be passing it back and forth.

public MovieSearch Pages {get; set;}  

//here's another way I tried it. This compiled but threw an error once I entered my first command. 
//Which makes sense, but I had to try
_pageCount = serializer.Deserialize<MovieSearch>(jsonReader).Pages;
Steven Parker
Steven Parker
231,108 Points

I was thinking you might do it at the same time as you set the results in GetMovies:

            //...
            using (var jsonReader = new JsonTextReader(reader)) {
                MovieSearch ms = serializer.Deserialize<MovieSearch>(jsonReader);
                _results = ms.Results;
                _pageCount = ms.Pages;
            }

If you have any further construction issues, could you share the entire environment in a workspace snapshot or github repo?