loader-logo

I have been asked to solve a coding challenge with below requirements.

  • Make a single page web application that uses an API from a movie catalog online database (we recommend https://www.omdbapi.com/).
  • This page must have a search feature and must list the top 3 matches by name, show the movie poster and link to the page when clicked on the poster.
  • Usage of libraries is recommended (i.e. Angular, React, Knockout, etc.).
  • Result must be a single HTML file and should perform nothing more than the above requested.

Getting Started

Step 1: Creating simple html page with one text box.

We need to create a simple HTML file with one input control in it.
We will use bootstrap framework for that.

 
<!DOCTYPE html> 
 <html>
  <head>
   <meta charset="utf-8" />
   <title>Movie Omdb</title>
   <link rel="stylesheet" 
   href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  </head>
  <body>
   <div class="container">
   <h2>Omdb movie records!</h2>
    <div class="row">
     <div class="form-group">
      <div class="col-sm-4">
       <input type="name" class="form-control" placeholder="Enter movie name">
      </div>
     </div>
    </div>
  </body>
 </html>

This will give you sleek clean HTML page with just one textbox where you can enter movie name to search for.

Step 2: Div where you show movie image along with it’s title.

Right after the first container, we created in above HTML code, add one more div with container class just like below.

...
<div class="container" style="margin-top:10px;">
 <div class="lightboxgallery-gallery clearfix">
  <a class="lightboxgallery-gallery-item" 
  target="_blank" href="#" data-title="This will be title" data-
  link="http://www.imdb.com/title/" data-alt="This will be title">
   <div class="col-md-4">
   <img src="Movie poster" title="This will be title" alt="This will be title">
   <div class="lightboxgallery-gallery-item-content">
   <span class="lightboxgallery-gallery-item-title">This will be title</span>
   </div>
   </div>
   </a>
 </div>
</div>
...

I am using lightboxgallery to show movie posters in cool form.
Below is a glimpse of how the lightbox will look like.

Off course for lightboxgallery have to include it’s JS and CSS files as well, for that add below cdn links to your HTML header.
Note: we are here to make all work just in one HTML file that’s why I hosted lightboxgallery widget libraries in my own cdn http://cdn.asimplify.com/lightboxgallery.

<link rel="stylesheet" href="http://cdn.asimplify.com/lightboxgallery/css/lightboxgallery-min.css">
<script src="http://cdn.asimplify.com/lightboxgallery/js/lightboxjs-custom.js"></script>

and add below code at the bottom of your HTML before ending body tag </body>

<script type="text/javascript">
  jQuery(function($) {
    $(document).on('click', '.lightboxgallery-gallery-item', function(event) {
      event.preventDefault();
      $(this).lightboxgallery({
        showCounter: true,
        showTitle: true,
        showDescription: true
      });
    });
  });
  </script>

If you test your HTML in the browser it will give you this error in the console. Because the lightbox gallery is based on the jQuery library you must have to include jQuery to work with a gallery.

You need to add a reference to your jQuery library. for that add below script in the header of your HTML file.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

If you click on broken image or title in your HTML page now, it will show a loader something like below this.

Now it’s time to move on and call fetch data from third party library and display using AngularJS.

Step 3: AngularJS service to fetch data from API.

I am using third party movie database OMDb API. Click me to get API key so that you can call database.

Below are the script we will put in the header of the HTML.

<script>
angular.module('MovieApp', [])
        .controller("MovieAppCtrl",
            [
                '$http', '$scope',
                function($http, $scope) {
                    $scope.MovieData = [];
                    $scope.GetMoviesData = function() {
                        try {
                            $http({
                                url: 'http://www.omdbapi.com/?apikey=####',
                                method: "GET",
                            }).then(
                                function(payload) {
                                    $scope.MovieData = payload.data;
                                },
                                function(){
								alert("Something is wrong. Please try again.");
								});
                        } catch (error) {
                            alert("Exception occured while fetching movie data.");
                        }
                    }
                }
            ]);
</script>

WAMP! YOU HAVEN’T SEEN ANYTHING IN THE BROWSER?
Open console to see the error in the browser.

What the heck is that?
On wait! we forgot to add AngularJS library here.
Put following link in the header.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

Now we are pretty good to go, we have to fetch the data successfully we just want to call the above AngularJS method on page load and display the data. Let’s do that!

Step 4: Display Fetched Record.

Use ng-app and ng-controller attributes in html and body respectively.

<html  ng-app="MovieApp">
....
<body ng-controller="MovieAppCtrl" ng-init="GetMoviesData()">
...

You will see this kind of response on API payload data object.

Don’t worry, you haven’t done anything wrong yet, just we need to filter out the data as we haven’t specified any search parameter yet.

Before going for searching let’s do some coding on how to display records from the AngularJS data model.

As from the above code, you saw that we fetched the data and assign data to the AngularJS scope variable MovieData. As this will be list of records we need to foreach fetched movie data records and show them on screen, apart from this we always need to limit display movie data counts to 3. So let’s just do that with below code.

 <div class="lightboxgallery-gallery clearfix">
        <a ng-repeat="movie in MovieData.Search | limitTo:3" class="lightboxgallery-gallery-item" target="_blank" ng-href="{{movie.Poster}}" data-title="{{movie.Title}}" data-link="http://www.imdb.com/title/{{movie.imdbID}}" data-alt="{{movie.Title}}">
          <div class="col-md-4">
            <img ng-src="{{movie.Poster}}" title="{{movie.Title}}" alt="{{movie.Title}}">
            <div class="lightboxgallery-gallery-item-content">
              <span class="lightboxgallery-gallery-item-title">{{movie.Title}}</span>
            </div>
          </div>
        </a>
    </div>

Now you see, we used ng-repeat on that Movie Data model and get the relevant data value using it’s properties within {{ }}.

Let’s do the searching.

Step 5: Searching Records.

What we have to do is we have to enable the user to type any movie name in the input text control and once he clicks the Submit button we need to fetch movies containing that string and show them.

Introduce a model in angular scope something like this $scope.Search = null;. and bind that model to the input text control so that the moment user type anything in the text control we will have model Search with that value.
Input text control looks like this.

<input type="name" class="form-control" placeholder="Enter movie name" ng-model="Search">

And introduce button click event like this

<button type="submit" class="btn btn-default" ng-click="GetMoviesData()">Submit</button>

Now we just to add that model to pass as a parameter to the API call so that we can get the filtered data.
for that just need to change the line of url with something like below.

url: 'http://www.omdbapi.com/?apikey=######&s='+$scope.Search,

Wuhoo you are now getting results, Congrats!

Full GitHub Code

3 Points