@workInProgress @ngdoc overview @name Tutorial: Step 5 @description
{@link tutorial.step_04 Previous} {@link http://angular.github.com/angular-phonecat/step-5/app Example} {@link tutorial Tutorial Home} {@link https://github.com/angular/angular-phonecat/compare/step-4...step-5 Code Diff} {@link tutorial.step_06 Next}
In this step, the View template remains the same but the Model and Controller change. We'll introduce the use of an angular {@link angular.service service}, which we will use to implement an `XMLHttpRequest` request to communicate with a server. Angular provides the built-in {@link angular.service.$xhr $xhr} service to make this easy. The addition of the `$xhr` service to our app gives us the opportunity to talk about {@link guide.di Dependency Injection} (DI). The use of DI is another cornerstone of the angular philosophy. DI helps make your web apps well structured, loosely coupled, and ultimately easier to test. __`app/js/controllers.js:`__
/* App Controllers */

function PhoneListCtrl($xhr) {
  var self = this;

  $xhr('GET', 'phones/phones.json', function(code, response) {
    self.phones = response;
  });

  self.orderProp = 'age';
}

//PhoneListCtrl.$inject = ['$xhr'];
__`test/unit/controllerSpec.js`:__
/* jasmine specs for controllers go here */
describe('PhoneCat controllers', function() {

  describe('PhoneListCtrl', function(){
    var scope, $browser, ctrl;

    beforeEach(function() {
      scope = angular.scope();
      $browser = scope.$service('$browser');

      $browser.xhr.expectGET('phones/phones.json').respond([{name: 'Nexus S'},
                                                            {name: 'Motorola DROID'}]);
      ctrl = scope.$new(PhoneListCtrl);
    });


    it('should create "phones" model with 2 phones fetched from xhr', function() {
      expect(ctrl.phones).toBeUndefined();
      $browser.xhr.flush();

      expect(ctrl.phones).toEqual([{name: 'Nexus S'},
                                   {name: 'Motorola DROID'}]);
    });


    it('should set the default value of orderProp model', function() {
      expect(ctrl.orderProp).toBe('age');
    });
  });
});
## Discussion: * __Services:__ {@link angular.service Services} are substitutable objects managed by angular's {@link guide.di DI subsystem}. Angular services simplify some of the standard operations common to web apps. Angular provides several built-in services (such as {@link angular.service.$xhr $xhr}). You can also create your own custom services. * __Dependency Injection:__ To use an angular service, you simply provide the name of the service as an argument to the controller's constructor function. The name of the argument is significant, because angular's {@link guide.di DI subsystem} recognizes the identity of a service by its name, and provides the name of the service to the controller during the controller's construction. The dependency injector also takes care of creating any transitive dependencies the service may have (services often depend upon other services). Note: if you minify the javascript code for this controller, all function arguments will be minified as well. This will result in the dependency injector not being able to identify services correctly. To overcome this issue, just assign an array with service identifier strings into the `$inject` property of the controller function. * __`$xhr`:__ We moved our data set out of the controller and into the file `app/phones/phones.json` (and added some more phones). We used the `$xhr` service to make a GET HTTP request to our web server, asking for `phone/phones.json` (the url is relative to our `index.html` file). The server responds with the contents of the json file, which serves as the source of our data. Keep in mind that the response might just as well have been dynamically generated by a sophisticated backend server. To our web server they both look the same, but using a real backend server to generate a response would make our tutorial unnecessarily complicated. Notice that the $xhr service takes a callback as the last parameter. This callback is used to process the response. In our case, we just assign the response to the current scope controlled by the controller, as a model called `phones`. Have you realized that we didn't even have to parse the response? Angular took care of that for us. * __Testing:__ The unit tests have been expanded. Because of the dependency injection business, we now need to create the controller the same way that angular does it behind the scenes. For this reason, we need to: * Create a root scope object by calling `angular.scope()` * Call `scope.$new(PhoneListCtrl)` to get angular to create the child scope associated with our controller. At the same time, we need to tell the testing harness that it should expect an incoming request from our controller. To do this we: * Use the `$service` method to retrieve the `$browser` service - this is a service that in angular represents various browser APIs. In tests, angular automatically uses a mock version of this service that allows you to write tests without having to deal with these native APIs and the global state associated with them. * We use the `$browser.expectGET` method to train the `$browser` object to expect an incoming http request and tell it what to respond with. Note that the responses are not returned before we call the `$browser.xhr.flush()` method. * We then make assertions to verify that the `phones` model doesn't exist on the scope, before the response is received. * We flush the xhr queue in the browser by calling `$browser.xhr.flush()`. This causes the callback we passed into the `$xhr` service to be executed with the trained response. * Finally, we make the assertions, verifying that the phone model now exists on the scope.
{@link tutorial.step_04 Previous} {@link http://angular.github.com/angular-phonecat/step-5/app Example} {@link tutorial Tutorial Home} {@link https://github.com/angular/angular-phonecat/compare/step-4...step-5 Code Diff} {@link tutorial.step_06 Next}