JSONP en AngularJS

  • Por
Ejercicio Ajax en el que realizamos un acceso a API REST que devuelve información mediante JSONP, realizado con el service $http de AngularJS.

JSONP es un mecanismo muy útil cuando estamos trabajando con Ajax en Javascript y queremos traernos datos que residen en otro servidor. Existe una problemática por la cual no puedes cargar datos con Javascript que te vengan desde servidores de otros dominios, pues puede darte un error de seguridad si es que el servidor al que te conectas no está configurado para aceptar solicitudes "cross domain".

Ahora no buscamos tanto introducir esta variante de JSON, pues ya la vimos con detalle en el artículo dedicado a JSONP. Simplemente te queremos explicar cómo debes usar JSONP dentro de AngularJS de una manera muy sencilla. Es un excelente ejercicio para practicar con todo lo que llevamos visto en el Manual de AngularJS.

Conexiones HTTP asíncronas en AngularJS

Para realizar solicitudes al servidor asíncronas (lo que se conoce habitualmente por Ajax en el mundo del desarrollo web) con AngularJS necesitamos un servicio llamado $http. Este "service" nos lo ofrece Angular de manera completa en su "core" y está preparado para hacer todo tipo de conexiones. Existen varios "shortcuts" que sirven para hacer operaciones típicas, con es el caso de traernos datos ofrecidos por medio de JSONP, así como GET, POST, etc.

En concreto para nuestro ejemplo usaremos el método jsonp() de $http, que recibe la URL del recurso JSONP al que quieres acceder. Al invocar ese método recibimos un objeto de respuesta sobre el que podemos configurar comportamientos para el caso de que la solicitud tenga éxito, fracaso, etc. Esto se hace con el conocido patrón promise de Javascript.

Nota: En el artículo dedicado a Ajax en AngularJS explicamos más detalles de este "service" ofrecido por AngularJS.

Función callback del JSONP en la URL de conexión

La verdad es que Angular hace todo el trabajo "sucio" por debajo y tú lo único que necesitas hacer es invocar el método correcto del service $http. Así que el método de acceso es prácticamente el mismo que si estuvieras trayendo los datos con un JSON normal.

En este caso la diferencia es que le tienes que indicar un nombre de la función callback de tu JSONP. La restauración del dato se hace de manera automática por AngularJS, lo único que necesitas es que en la URL compuesta de tu JSONP indiques el nombre de la función callback como "JSON_CALLBACK". Eso en JSONP se indica con el parámetro en la URL de conexión llamado "callback", que escribes de la siguiente manera.

Nota: Esa función callback es la que usamos en Javascript del navegador para restaurar los datos del JSONP. Como decimos es algo que realmente no necesitas preocuparte mucho, pues es transparente para ti. Si quieres obtener más información podrías consultar el artículo sobre JSONP.

http://example.com/url.json?callback=JSON_CALLBACK

Ejemplo realizado en AngularJS para traer datos de API REST con JSONP

Ahora vamos a realizar un ejemplo en AngularJS para practicar lo aprendido. De este modo verás que es todo muy sencillo. En este ejemplo traemos datos de cervezas de un API REST pública llamada "Open Beer Database". Los datos los obtenemos por JSONP y puedes ver un ejemplo de conexión y código en esta página de la documentación del API.

http://openbeerdatabase.com/documentation/examples-jsonp

En nuestro caso concreto accedemos a cervezas en vez de cervecerías, pero el ejemplo es bien similar. Nuestra URL para obtener datos del API es como esta:

http://api.openbeerdatabase.com/v1/beers.json?callback=JSON_CALLBACK&query=ale

Como puedes ver, en la URL indicamos en el parámetro "callback" el nombre de la función callback que nos pide Angular. Además hay un segundo parámetro llamado "query" con el que podemos expresar unas palabras clave para hacer búsquedas de cervezas que contengan esas palabras.

Sabiendo esto, ahora pasemos a ver nuestro código. Esta es la parte del HTML.

<div ng-app="apiApp" ng-controller="apiAppCtrl as vm">
  <h1>Pruebo Ajax con JSONP</h1>
  <p>
      Busca cerveza:
      <input type="text" ng-model="vm.nombre"> <input type="button" value="Buscar" ng-click="vm.buscaCervezas()">
  </p>
  <ul>
      <li ng-repeat="cerveza in vm.cervezas"><span>{{cerveza.name}},</span> {{ cerveza.description }}</li>
  </ul>
</div>

Como ves, tenemos un campo de texto donde podemos escribir un dato y un botón de buscar. Al darle a buscar llamamos a un método de nuestro "scope" para traernos las cervezas que tengan el texto escrito en el campo de texto, ya sea en su nombre o descripción.

Luego tenemos un bucle definido con ng-repeat en el que recorremos una colección de cervezas.

Ahora puedes ver la parte del Javascript:

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

function controladorPrincipal($scope, $http){
    var vm=this;
    
    vm.buscaCervezas = function(){
        var url = "http://api.openbeerdatabase.com/v1/beers.json?callback=JSON_CALLBACK";
        if(vm.nombre){
            url += "&query=" + vm.nombre;
        }
        $http.jsonp(url).success(function(respuesta){
            console.log("res:", respuesta);
            vm.cervezas = respuesta.beers;
        });
    }
}

Bien, supongo que estos códigos ya te irán sonando y en concreto este ejercicio es muy parecido al anterior en el que conocimos Ajax. En la parte importante, nuestro controlador, apreciarás que tenemos un método llamado buscaCervezas() que es el que se encarga de hacer todo el trabajo.

En ese método primero construimos la URL para acceder al API, agregándole el nombre de la cerveza que quieres buscar.

Luego accedemos por medio de $http.jsonp() a la URL construida y definimos una función que se ejecutará en caso de éxito de la conexión Ajax (success). en esa función simplemente volcamos las cervezas encontradas en el scope, con lo que se actualiza automáticamente la vista en el bloque donde teníamos la directiva ng-repeat de nuestro HTML.

Con esto es todo. Solo te queda practicar lo aprendido por tu cuenta para no dejarte un detalle sobre las conexiones JSONP en AngularJS.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Luis Julian

06/11/2014
componer un jsonp en el servidor
¿y q código usaría para componer un archivo jsonp en el servidor? no para consumirlo en el cliente sino para producirlo con los datos de una base de datos. gracias.

yeison

07/11/2014
subir archivo
de que forma se subiria un archivo a un api REST desde angularjs ?

jordi_lopez-249240

02/4/2015
Añadir la búsqueda por el nombre de la cerveza
¡Buenas, muy buen tutorial!
El único detalle personal, es que el caso de buscar por cervezas sólo me ha funcionado cuando he introducido el if statement de vm.nombre dentro de la función buscaCervezas

¡Espero sea de ayuda!

hernan_albertario

29/12/2015
La url de la Api database esta caida?
Buen dia, puede ser que la url que se usa para el ejemplo haya expirado? De ser asi con cúal otra base libre puedo probar?
Muchas gracias por este y todos los demas articulos!
Saludos

Jorge

03/2/2016
LInk API
Ups, parece que opendatabase beer no está ya operativa... :(

vicmagar

16/6/2016
URL Mala
El dominio esta desactivado http://api.openbeerdatabase.com/. hay otro con el cual se pueda hacer el ejemplo?

yo

22/8/2016
comentarios sin respuesta
No sé para que hay una sección de "comentarios" si luego no los respondéis.
Eso queda fatal.

Jhader Hurtado

05/10/2016
Duda
¿Por que en el controller no se coloca el $http y despues el nombre de la función?
y ¿Por que a la funcion principal se le agrega el $scope?