Introducción a Angular JS

Listar y crear registros usando el servicio ngResource Más videos

Descripción del tema

En el tutorial anterior vimos como crear servicios para hacer peticiones Ajax al servidor, en este tema veremos como podemos consultar un API RESTful para consultar el listado de bookmarks y crear uno nuevo.

Angular JS viene con un servicio llamado $ngResource, este servicio nos permite hacer conexiones vía REST a nuestra API para enviar y recibir información. Internamente ngResource utiliza el servicio $http que vimos en el tutorial anterior.

Usar ngResource en lugar de $http tiene varias ventajas, sobre todo cuando queremos hacer operaciones CRUD, ya que automáticamente nos define los métodos necesarios para guardar, listar y consultar un API de tipo REST, además es muy sencillo agregar nuevos métodos. Hacer esto con el servicio $http nos requerirá algunas lineas de código adicionales, pero es completamente posible.

Los métodos que define de manera automática son los siguientes:

  1. get()
  2. query()
  3. save()
  4. remove()
  5. delete()
En este tema nos enfocaremos solamente en como utilizar el método query y el método save.

Definir dependencias

El servicio ngResource no viene incluido dentro de la librería principal de Angular JS, lo tenemos que incluir manualmente y definirlo en las dependencias de nuestro módulo, vamos a insertar el siguiente script en el documento HTML.

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular-resource.min.js"></script>

Lo tenemos que importar por debajo de la librería de Angular JS para no tener errores. Ahora en el archivo app.js agregamos el siguiente código.

angular.module('Bookmarks',[
    //dependencies here
    'ngResource' //<----
])

Cuando creamos nuestro módulo principal dijimos que el segundo parámetro corresponde a un arreglo con las dependencias de nuestra aplicación. Ha llegado el momento de comenzar a agregar dependencias.

Configuración básica del servicio ngResource

Ya dijimos que la persistencia debemos manejarla en servicios, para este ejemplo vamos a usar un servicio que haga uso del ngResource, pero a diferencia del tutorial anterior, en esta ocasión vamos a crear el servicio usando una factoría. 

Las factorías a diferencia de los servicios que estudiamos en el tema anterior, nos permiten crear y retornar el servicio usando en una función. En este caso regresaremos el ngResource con las configuraciones necesarias.

//Step 1
.factory('Bookmark',function($resource){ //Step 2
    //Step 3
    return $resource('http://bookmarks-angular.herokuapp.com/api/bookmarks/:id');
})
  1. En el paso uno definimos la factoría con el método factory, en el primer parámetro le asignamos el nombre del servicio, en este caso Bookmark, y el segundo parámetro es la función que creará el servicio Bookmark.
  2. En el paso dos agregamos como parámetro el servicio ngResource, el cual exta disponible bajo el identificador $resource. Angular inyectará este servicio automáticamente, solo tenemos que asegurarnos nombrarlo exactamente igual.
  3. En el paso tres configuramos el recurso con la URL donde está nuestra API, algo importante a destacar es que definimos el parámetro :id, este lo usaremos para consultar, actualizar o borrar un bookmark.

Una factoría siempre debe regresar un objeto o instancia del servicio que crearemos, en este ejemplo estamos regresando el recurso ya configurado y listo para ser usado en nuestros controladores.

Listar bookmarks existentes

Para solicitar el listado de bookmarks que actualmente se encuentran almacenadas en el servidor, en el controlador usamos el método query de la siguiente manera.

.controller('MainController',function($scope,Category,Bookmark){ //Step 1
    $scope.name = 'Carl';

    Category.getAll(function(data){
        $scope.categories = data.categories;
        $scope.currentCategory = data.categories[0]; //Step 2
        $scope.bookmarks = Bookmark.query(); //Step 3
    });
 
    //...

});
  1. En el paso uno inyectamos el nuevo servicio que creamos usando la factoría.
  2. El paso dos se ejecuta cuando el servidor responde con el listado de categorías, aquí solamente seleccionamos la categoría cero para filtrar los bookmarks.
  3. En el paso tres ejecutamos el método query(), este método hace una petición GET hacia la url que definimos.

Antes de probar nuestros cambios necesitamos cambiar el template para manejar correctamente las categorías, anteriormente estábamos usando strings solamente, ahora estamos usando objetos, por lo tanto debemos actualizar nuestro template de la siguiente manera.

<!-- sidebar -->
<div class="column col-sm-3" id="sidebar">
    <p class="nav-title">
      Categories 
      <a href="#" class="pull-right"><i class="glyphicon glyphicon-folder-open"></i></a>
    </p>
    <ul class="nav">
        <li ng-repeat="category in categories" ng-class="{active: isCurrentCategory(category)}">
            <a href="#" ng-click="setCurrentCategory(category)"> <i class="glyphicon glyphicon-tags"></i> {{category.name}}</a>
        </li>
    </ul>
</div>
<!-- /sidebar -->

<!-- main -->
<div class="column col-sm-9" id="main">
    <div class="padding">
      <div class="full col-sm-9">
        
          <!-- content -->
          <h2>
            Category: {{currentCategory.name}}
            <a ng-click="showWindow()" href="#" class="btn btn-primary btn-xs pull-right"><i class="glyphicon glyphicon-plus-sign"></i> New bookmark</a>
          </h2>
          <ul>
            <li ng-repeat="bookmark in bookmarks | filter: {category: currentCategory.name}">
                <p>
                    <a href="/courses/introduccion-a-angular-js/articles/%7B%7Bbookmark.url%7D%7D/">{{bookmark.title}}</a> 
                    <i ng-click="remove(bookmark.id)" class="glyphicon glyphicon-trash"></i>
                    <i ng-click="showWindow(bookmark)" class="glyphicon glyphicon-pencil"></i><br/>
                    <small>{{bookmark.url}}</small>
                </p>
            </li>
        </ul>
          
          
        
      </div><!-- /col-9 -->
    </div><!-- /padding -->
</div>
<!-- /main -->
  1. En el sidebar solo hemos cambiado dos cosas, a la función isCurrentCategory y setCurrentCategory le estamos enviando el objeto y no solamente el nombre de la categoría.
  2. En el listado de bookmarks desplegamos el nombre de la categoría seleccionada usando currentCategory.name y también cambiamos el filtro. Todo lo demás sigue exactamente igual.

Ya casi estamos listos para probar nuestros cambios, solo nos queda modificar la función isCurrentCategory de la siguiente manera.

$scope.isCurrentCategory = function(category){
    return $scope.currentCategory.id === category.id;
}

Ya que estamos usando objetos para manejar las categorías, necesitamos comparar los identificadores. Una vez que cambiamos esto ya podremos ver nuestra aplicación listando los bookmarks que actualmente están en la base de datos del servidor.

Angular ngResource

Angular ngResource

Crear un nuevo Bookmark

Vamos a crear nuevos bookmarks utilizando el método save, este método hará una petición Ajax a la URL que definimos en el ngResource de tipo POST, la API que esta en Heroku tiene soporte para recibir este tipo de peticiones y espera el siguiente objeto json en el payload del request.

{
    "title"       : "The title of the new bookmark",
    "url"         : "http://testing.com",
    "category_id" : 2
}

Con esto en mente modificaremos el código del método save que ya tenemos en el controlador. Ahora en lugar de solamente agregar el objeto al arreglo local de bookmarks, también haremos la petición al servidor para guardarlo en la base de datos, en Heroku la base de datos es PostgreSQL.

$scope.save = function(bookmark){
    if($scope.bookmarkForm.$valid){
        if(!bookmark.id){
            var record = new Bookmark(); //Step 1
            
            record.title = bookmark.title; //Step 2
            record.url = bookmark.url;
            record.category_id = bookmark.category.id;

            record.$save(function(){ //Step 3
                $scope.bookmarks.push(record); //Step 4
            });
        }
        $('#bookmarkModal').modal('hide');
    }
}
  1. En el paso uno creamos una instancia de nuestro servicio Bookmark usando la palabra reservada new.
  2. En el paso dos agregamos la información (title, url, category_id) a la instancia del servicio que creamos en el paso uno, esta información es la que se enviará al servidor y es la que el API está esperando recibir.
  3. En el paso tres invocamos el método $save de la instancia del servicio, este método es el que hace la petición ajax y nos regresa una promesa.
  4. En el ultimo paso insertamos el record al arreglo de bookmarks, cuando el servidor responde. 

Idealmente usaremos solamente el método get y query del servicio Bookmark, ya que tenemos a nuestra disposición el método $save, $delete y $remove an cada instancia de Bookmark. Es importante resaltar que estos métodos inician con el signo $, esto nos indica que son métodos de la instancia.

Si probamos la app en el navegador y creamos un nuevo bookmark, veremos que se está haciendo una petición al servidor para guardar el bookmark en la base de datos.

ngResource

Guardando un bookmark

Por el momento hasta aquí llegaremos en este tutorial, en el próximo veremos como editar los bookmarks existentes y también como borrarlos utilizando el ngResource que ya tenemos configurado.

Recuerda que puedes descargar el código fuente, y el video desde el área de miembros de Quizzpot.com, si tienes dudas puedes usar el foro.

Te gustaría recibir más tutoriales como este en tu correo?

Este tutorial pertenece al curso Introducción a Angular JS, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.

Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!

Instructor del curso

Crysfel3

Autor: Crysfel Villa

Ha participado en varios proyectos con Angular y es participante activo del grupo de Angular NYC.

Ver Demostración