> Manuales > Manual de AngularJS

Nos introducimos en el uso de Ajax mediante AngularJS. Lo vamos a hacer de una manera muy habitual en el desarrollo con este framework que es accediendo a un servicio web que nos ofrece un API REST.

A la vez que aprendemos técnicas de Ajax vamos a repasar diversas de las prácticas que ya te hemos ido contando a lo largo del Manual de AngularJS.

Ya lo sabes, Ajax es una solicitud HTTP realizada de manera asíncrona con Javascript, para obtener datos de un servidor y mostrarlos en el cliente sin tener que recargar la página entera. Además para los despistados que no lo sepan todavía, tenemos un artículo que te explica muy bien qué son exactamente las API REST.

Service $http

El servicio $http (service en inglés, tal como se conoce en AngularJS) es una funcionalidad que forma parte del núcleo de Angular. Sirve para realizar comunicaciones con servidores, por medio de HTTP, a través de Ajax y vía el objeto XMLHttpRequest nativo de Javascript o vía JSONP.

Después de esa denominación formal, que encontramos en la documentación de AngularJS, te debes de quedar por ahora en que nos sirve para realizar solicitudes y para ello el servicio $http tiene varios tipos de acciones posibles. Todos los puedes invocar a través de los parámetros de la función $http y además existen varios métodos alternativos (atajos o shortcuts) que sirven para hacer cosas más específicas.

Entre los shortcuts encuentras:

$http.get()
$http.post()
$http.put()
$http.delete()
$http.jsonp()
$http.head()
$http.patch()

Tanto el propio $http() como las funciones de atajos te devuelven un objeto que con el "patrón promise" te permite definir una serie de funciones a ejecutar cuando ocurran cosas, por ejemplo, que la solicitud HTTP se haya resuelto con éxito o con fracaso.

Nota: Si vienes de jQuery ya habrás podido experimentar las promesas "promise" en las llamadas a la función $.ajax, $.get, $post, etc. En AngularJS funciona de manera muy similar.

El service $http es bastante complejo y tiene muchas cosas para aportar soluciones a las más variadas necesidades de solicitudes HTTP asíncronas. De momento nos vamos a centrar en lo más básico que será suficiente para realizar un ejemplo interesante.

Inyección de dependencias con $http

Si vas a querer usar el servicio $http lo primero que necesitarás será inyectarlo a tu controlador, o a donde quiera que lo necesites usar. Esto es parecido a lo que mostramos cuando estábamos practicando con controladores e inyectábamos el $scope.

angular
    .module('apiApp', [])
    .controller('apiAppCtrl', ['$http', controladorPrincipal] );

Como puedes ver, en la función de nuestro controlador, llamada controladorPrincipal, le estamos indicando que recibirá un parámetro donde tiene que inyectar el service $http.

Al declarar la función recibirás esa dependencia como parámetro.

function controladorPrincipal($http){

Ahora, dentro del código de ese controlador podrás acceder al servicio $http para realizar tus llamadas a Ajax.

Realizar una llamada a $http.get()

El método get() sirve para hacer una solicitud tipo GET. Recibe diversos parámetros, uno obligatirio, que es la URL y otro opcional, que es la configuración de tu solicitud.

$http.get("http://www.example.com")

Lo interesante es lo que nos devuelve este método, que es un objeto "HttpPromise", sobre el cual podemos operar para especificar el comportamiento de nuestra aplicación ante diversas situaciones.

Respuesta en caso de éxito

De momento, veamos qué deberíamos hacer para especificarle a Angular lo que deve de hacer cuando se reciba respuesta correcta del servidor.

$http.get(url)
.success(function(respuesta){
//código en caso de éxito
});

Como puedes ver en este código es que $http nos devuelve un objeto. Sobre ese objeto invocamos el método success() que sirve para indicarle la función que tenemos que ejecutar en caso de éxito en la solicitud Ajax. Esa función a su vez recibe un parámetro que es la respuesta que nos ha devuelto el servidor.

Nota: En Angualar 1.4 cambiaron el estándar de respuesta en caso de éxito o fracaso de la conexión Ajax. El nuevo mecanismo es bastante parecido, con funciones callback que se cargan a partir del método then(). Lo tienes descrito con ejemplos en el artículo de Estándar del patrón promise para los métodos del servicio $http en Angular 1.4.

Ejemplo completo de solicitud Ajax con $http

Vistos estos nuevos conocimientos sobre el "service" $http estamos en condiciones de hacer un poco de Ajax para conectarnos con un API REST que nos ofrezca unos datos. Esos datos son los que utilizaremos en nuestra pequeña aplicación para mostrar información.

Nota: Vamos a usar un API llamada REST Countries, que puedes encontrar en http://restcountries.eu/

Este API nos devuelve JSON con datos sobre los países del mundo. En principio puedes hacer diversas operaciones con los comandos sobre el API, pero vamos a ver solamente unas pocas que nos permiten recibir los datos de los países agrupados por regiones.

Las URL que usaremos para conectarnos al API son como estas:

http://restcountries.eu/rest/v1/region/africa
http://restcountries.eu/rest/v1/region/europe

Puedes abrirlas en tu navegador y observar cómo la respuesta es un conjunto de datos en notación JSON.

Aunque sencilla, esta aplicación ya contene varias cosillas que para una mejor comprensión conviene ver por separado.

Este es nuestro HTML:

<div ng-app="apiApp" ng-controller="apiAppCtrl as vm">
  <h1>Pruebo Ajax</h1>
  <p>
      Selecciona:
      <select ng-model="vm.url" ng-change="vm.buscaEnRegion()">
       <option value="http://restcountries.eu/rest/v1/region/africa">Africa</option>
        <option value="http://restcountries.eu/rest/v1/region/europe">Europa</option>
        <option value="http://restcountries.eu/rest/v1/region/americas">America</option>
      </select>
  </p>
  <ul>
      <li ng-repeat="pais in vm.paises">
        País: <span>{{pais.name}}</span>, capital: {{pais.capital}}
      </li>
  </ul>
</div>

Puedes fijarte que tenemos un campo SELECT que nos permite seleccionar una región y para cada uno de los OPTION tenemos como value la URL del API REST que usaríamos para obtener los países de esa región.

Aprecia que en el campo SELECT está colocada la directiva ngChange, que se activa cuando cambia el valor seleccionado en el combo. En ese caso se hace una llamada a un método llamado buscaEnRegion() que veremos luego escrito en nuestro controlador.

También encontrarás una lista UL en la que tienes una serie de elementos LI. Esos elementos LI tienen la directiva ngRepeat para iterar sobre un conjunto de países, de modo que tengas un elemento de lista por cada país.

Ahora puedes fijarte en el Javascript:

angular
    .module('apiApp', [])
    .controller('apiAppCtrl', ['$http', controladorPrincipal]);

function controladorPrincipal($http){
    var vm=this;
    
    vm.buscaEnRegion = function(){
        $http.get(vm.url).success(function(respuesta){
            //console.log("res:", respuesta);
            vm.paises = respuesta;
        });
    }
}

Creamos un module y luego un controlador al que inyectamos el $http como se explicó al inicio del artículo.

Luego, en la función que construye el controlador, tenemos un método que se llama buscaEnRegion() que es el que se invoca al modificar el valor del SELECT. Ese método es el que contiene la llamada Ajax.

Realmente el Ajax de este ejercicio se limita al siguiente código:

$http.get(vm.url).success(function(respuesta){
//console.log("res:", respuesta);
vm.paises = respuesta;
});

Usamos el shortcut $http.get() pasando como parámetro la URL, que sacamos del value que hay marcado en el campo SELECT del HTML. Luego se especifica una función para el caso "success" con el patrón "promise". Esa función devuelve en el parámetro "respuesta" aquello que nos entregó el API REST, que es un JSON con los datos de los países de una región. En nuestro ejemplo, en caso de éxito, simplemente volcamos en un dato del modelo, en el "scope", el contenido de la respuesta.

En concreto ves que la respuesta se vuelca en la variable vm.paises, que es justamente la colección por la que se itera en el ng-repeat de nuestro HTML.

Código completo del ejercicio

Quizás se puede ver y entender mejor el ejercicio en global si vemos el código completo de una sola vez. Pero ya sabes que para aprender bien las cosas debes practicar por tu cuenta, creando ahora tu propio ejemplo Ajax, accediendo a este API REST o a cualquier otra que te apetezca. Verás que es muy sencillo y con poco código puedes hacer cosas bastante más espectaculares de lo que nosotros hemos realizado en este ejemplo.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Probando Ajax en AngularJS</title>
    <style>
        body{ font-family: sans-serif;}
        li{
            font-size: 0.8em;
        }
        li span{
            font-weight: bold;
        }
    </style>
</head>
<body>
<div ng-app="apiApp" ng-controller="apiAppCtrl as vm">
  <h1>Pruebo Ajax</h1>
  <p>
      Selecciona:
      <select ng-model="vm.url" ng-change="vm.buscaEnRegion()">
       <option value="http://restcountries.eu/rest/v1/region/africa">Africa</option>
        <option value="http://restcountries.eu/rest/v1/region/europe">Europa</option>
        <option value="http://restcountries.eu/rest/v1/region/americas">America</option>
      </select>
  </p>
  <ul>
      <li ng-repeat="pais in vm.paises">País: <span>{{pais.name}}</span>, capital: {{pais.capital}}</li>
  </ul>

</div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
    <script>
    angular
        .module('apiApp', [])
        .controller('apiAppCtrl', ['$http', controladorPrincipal]);

    function controladorPrincipal($http){
        var vm=this;
        
        vm.buscaEnRegion = function(){
            $http.get(vm.url).success(function(respuesta){
                //console.log("res:", respuesta);
                vm.paises = respuesta;
            });
        }
    }

    </script>
</body>
</html>

En el siguiente artículo explicaremos cómo acceder por Ajax a un JSON pero con JSONP.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual