Angular $http

Objectives

  • Use $http to access an API resource

  • Use $scope.$watch to observe model changes

What is $http?

$http is a core Angular service provided for you to use. It allows the browser to send HTTP requests and responses, similar to AJAX calls in jQuery.

Using $http

We can use the $http service to request data from an external source. $http can be incorporated into an Angular app via dependency injection. This can happen on either the module or controller.

In our example, we'll include $http as a dependency for each controller. Specifically, we'll be using $http to access a public API that allows Cross Origin Resource Sharing (CORS).

Getting Started

Take a look at the sample code, which should have scaffolds for index.html and js/app.js. Add the following to app.js:

var movieApp = angular.module('MovieApp', []);

movieApp.controller('SearchCtrl', ['$scope', '$http', function($scope, $http) {

}]);

Yes, we are making yet another OMDB app. This time, with Angular.

So let's setup what we'll need to perform a request to OMDB.

  • A method to search for a movie (form input)

  • A model to store the search term

  • A URL to send the term to (OMDB)

  • A function to receive and process the response

First, let's setup the form and model. (don't forget to setup ng-app and ng-controller first)

In index.html

<h1>Movie App</h1>
<form class="form" ng-submit="search()">
  <div class="form-group">
    <label>Search for a Movie:</label>
    <input type="text" class="form-control" ng-model="searchTerm">
    <input type="submit" class="btn btn-primary">
  </div>
</form>

We'll see that we created a model called searchTerm bound to the input field, and a function called search() to execute when the form submits.

Now for the controller. Inside the SearchCtrl within js/app.js:

$scope.searchTerm = '';

$scope.search = function() {
  var req = {
    url: 'http://www.omdbapi.com',
    method: 'GET',
    params: {
      s: $scope.searchTerm,
    }
  }

  $http(req).then(function success(res) {
    //do something with the response if successful
    console.log(res);
  }, function error(res) {
    //do something if the response has an error
    console.log(res);
  });
};

We just added a variable called searchTerm to $scope, as well as added the search() function. We also created an object to store the URL and search params (those search params will be converted to a querystring by $http).

Lastly, we call $http to perform a request with the req object, then expect success and error callbacks. Try running this code and see what res contains. Note that res is the entire response, and we need to call res.data to access the payload of the response.

Rendering Movies

In order to render movies to the page, we need to attach the data received to $scope. Let's add a movies variable to the controller's scope, and assign the data if the response is OK:

$scope.movies = [];

$http.get(req).then(function success(res) {
  if (res.status === 200) {
    $scope.movies = res.data.Search;
  }
  console.log(res);
}, function error(res) {
  console.log(res);
});

Note that we obtain res.data.Search because the response is an object with a key called Search. The value associated with this key has our results.

Printing them out requires ng-repeat in index.html

<div class="well" ng-repeat="movie in movies track by $index">
  {{movie}}
</div>

You'll see that each movie is an object. Take a few minutes and clean this up so each well displays the title and poster of each movie.

Related: Use ng-src when including Angular markup in an image link. It's a common problem that pops up. Link to the ngSrc documentation.

$watch

So far, we've been having our views update when changes are made to the model. What if we want to "listen" to our model and have our controller react to changes? We can use $watch in order to observe and react to model changes. For example, maybe we want the movie search to happen when the user changes the searchTerm value.

// attaching a $watch function to $scope, defining two values:
// 1. The value to watch
// 2. A function that runs when the value changes, with the new and old values
$scope.$watch('searchTerm', function(newVal, oldVal) {
  // perform the search here
});

Note that this works for expressions, but not collections (like objects and arrays). For objects and arrays, you can take advantage of $watchGroup and $watchCollection. Documentation is here.

Last updated