Angular Walkthrough- Movie Posters

You are seriously rocking it with Angular, but our app is a little bland at this point. It could use some improvements, like a photo to go with each movie. This is a great opportunity because we can utilize another API to fetch an image just from the movie title. We'll use the Open Movie Database to do this. Let's get started!

In app.js, create this function in our controller:

function fetchMovieImage(movie) {
}

In the function body, we will make a GET request to the Open Movie Database. This will look up a movie by title and respond with the poster image. Check out the docs at http://www.omdbapi.com if you're interested. If no movie is found, then we'll show the default image we have now. This function is pretty similar to the rest we've done so far. Let's go ahead and write it:

/**
 * We use the $http method to send a GET request to a movie poster API. 
 * We add the movie name into the middle of the url so the API knows what to search for.
 * We use the .then() method to pass in our success and error functions. 
 */
function fetchMovieImage(movie) {
  $http({
     method: 'GET',
     url: 'https://www.omdbapi.com/?t='+movie.title+'&y=&plot=short&r=json',
     headers: {
       'Content-Type': undefined
     }
  }).then(function(response){
      //If the response data was valid, set the movie image
      if(response.data.Poster != null) 
        movie.image = response.data.Poster; //Set the movie image to the url we got from the server
  },function(error){
      console.log(error);//Something went wrong, log the error
  })
}

Now we need to call this function whenever we load a new movie. This will load up a picture for each movie in the array. Add this line to the success callback of our init() function:

angular.forEach(collection.movies, function(movie) {
    fetchMovieImage(movie);
});

Your complete init() function should now look like:

 function init() {
      /**
       * Use the $http method to send a GET request to our movie API. 
       * We provide some details in the first paramater. 
       * We use the .then() method to pass in our success and error functions. 
       */
      $http({
           method: 'GET',
           url: API+'movies',
           headers: {
             'Content-Type': undefined
           }
          }).then(function success(response) {
              //If this was successfull, handle the data from the server
              collection.movies = response.data; //Copy the response data into our movie array
              angular.forEach(collection.movies, function(movie) {
                fetchMovieImage(movie);
            });
          }, function error(error){
              console.log(error);
       });
    }

We will also call this function when adding a new movie. If we skipped this step, we would need to refresh the page before images would show up. Add this line in the success callback inside the createMovie function:

fetchMovieImage(response.data);

Your complete createMovie function should now look like:

function createMovie(movie) {
        /**
         * Like before, we use the $http method to send a POST request to our movie API. 
         * Because its a POST request we provide the data we want to send.
         * We use the .then() method to pass in our success and error functions. 
         */
        $http({
            method: 'POST',
            url: API+'movies',
            data: movie
        }).then(function successCallback(response) {
            //Make sure the response has the data we need
            if(response.data.title != null && response.data.description != null) {
                //Log the data just for reference
                console.log(JSON.stringify(response.data)); //We use JSON.stringify to make the response data human-readable
                collection.newMovie = {}; //Clear the newMovie data to reset the form. 
                collection.movies.push(response.data); //Add the new movie to our movie array
                collection.expandNewMovieEntry = false; //Close the movie creation form
                fetchMovieImage(response.data);
            } else {
                //The response was missing data, something went wrong. 
                console.log("Failed: "+JSON.stringify(response.data)); //We use JSON.stringify to make the response data human-readable
            }
        }, function errorCallback(error) {
            console.log(error);
        });
    }

Now we need to render these images in the html. To do this, you can use the ng-src directive, like so:

<!-- Movie Image -->
<div class="movie-image">
  <img ng-src="{{movie.image}}" width="200" height="300"/>  
</div>

A good place to add the image is between the title and the description. This section should now look like this:

<!--Movie Entry-->
<div class='card thin-card' ng-repeat='movie in collection.movies'>
  <div>
    <!-- Movie Title -->
    <h1 class='title movie-title'> {{ movie.title }} </h1>

    <!-- Movie Image -->
    <div class="movie-image">
      <img ng-src="{{movie.image}}" width="200" height="300"/>  
    </div>

    <!-- Movie Description -->
    <p class="movie-description"> {{ movie.description }} </p>

    <!-- Movie Review Icon -->
    <div ng-hide='movie.expandNewReviewEntry' class='form-group center-wrapper'>
      <img ng-click='movie.expandNewReviewEntry = true' class='review-dropdown-icon' src='public/plus.svg' />
    </div>
    ...

There you go! You should now have a beautiful webapp!

All Done!

That's it! You have a fully working webapp! Along the way you learned about cool technologies like AngularJS and Bower. You learned how to use controllers and servies to control the logic of your app. You even learned how to use directives to connect your html to the data itself. Give yourself a big round of applause for this really awesome project you've made!

You're free to use, share, and modify this code however you want. If you want to extend this project into something even cooler, go for it! We can't wait to see what you come up with!