Hola a todos, hoy quiero hablar un poco sobre AngularJS y como gracias al módulo ngResource es muy fácil consumir un servicio REST construido con ASPNET Web API.


Para el demo, voy a utilizar la plantilla empty de ASPNET Web Application de Visual Studio, y solo marcar las casillas de MVC y Web API para agregar las referencias a los paquetes.

Lo primero, es tener el servicio, así que vamos a crear una clase sencilla Customer con 3 propiedades:


public class Customer
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }
}

Luego de ello, para crear el servicio, nos vamos a apoyar del scaffolding de Web API para que nos genere todo el CRUD para la clase creada anteriormente, he seleccionado el template Web API 2 Controller with actions, using Entity Framework

Web API Scaffolding

Luego de dar clic en el botón adicionar, se genera nuestro CustomersController:


public class CustomersController : ApiController
{
    private DemoContext db = new DemoContext();

    // GET: api/Customers
    public IQueryable GetCustomers()
    {
        return db.Customers;
    }

    // GET: api/Customers/5
    [ResponseType(typeof(Customer))]
    public IHttpActionResult GetCustomer(int id)
    {
        Customer customer = db.Customers.Find(id);
        if (customer == null)
        {
        return NotFound();
        }

        return Ok(customer);
    }

    // PUT: api/Customers/5
    [ResponseType(typeof(void))]
    public IHttpActionResult PutCustomer(int id, Customer customer)
    {
        if (!ModelState.IsValid)
        {
        return BadRequest(ModelState);
        }

        if (id != customer.Id)
        {
        return BadRequest();
        }

        db.Entry(customer).State = EntityState.Modified;

        try
        {
        db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
        if (!CustomerExists(id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/Customers
    [ResponseType(typeof(Customer))]
    public IHttpActionResult PostCustomer(Customer customer)
    {
        if (!ModelState.IsValid)
        {
        return BadRequest(ModelState);
        }

        db.Customers.Add(customer);
        db.SaveChanges();

        return CreatedAtRoute("DefaultApi", new { id = customer.Id }, customer);
    }

    // DELETE: api/Customers/5
    [ResponseType(typeof(Customer))]
    public IHttpActionResult DeleteCustomer(int id)
    {
        Customer customer = db.Customers.Find(id);
        if (customer == null)
        {
        return NotFound();
        }

        db.Customers.Remove(customer);
        db.SaveChanges();

        return Ok(customer);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
        db.Dispose();
        }
        base.Dispose(disposing);
    }

    private bool CustomerExists(int id)
    {
        return db.Customers.Count(e => e.Id == id) > 0;
    }
}

Listo, ya tenemos el servicio, ahora en la parte cliente, como referencias necesitamos angular.js y angular-resource.js.


<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-resource.js"></script>

Crear el archivo app.js para ser el módulo de la aplicación e inyectar el módulo ngResource:


(function () {
    'use strict';
    angular.module('app', ['ngResource']);
})();

Ahora, vamos a crear un servicio que exponga el endpoint, este lo crearemos dentro de una carpeta Services con el nombre apiservice.js


(function () {
    'use strict';
    angular
        .module('app')
        .factory('apiservice', apiservice);

    apiservice.$inject = ['$http','$resource'];

    function apiservice($http, $resource) {
        var resourceUrl = '/api/customers/:id';
        return $resource(resourceUrl,
            { id: "@id" },
            { update: { method: "PUT" }
            });
    }
})();


Como puntos a revisar, se inyecta $resource perteneciente al módulo ngResource, y se retorna $resource que como primer parámetro requiere la ruta del servicio, segundo parámetro el paramétro id definido en la ruta, y el tercer parámetro estpa pensando para poder extender el funcionamiento, se ha declarado un método con el nombre update que va a trabajar con el verbo HTTP Put ya que por defecto $resource no viene con dicho verbo implementado, tal como se ve en la documentación oficial: Documentación ngResource:

ngResource métodos http

Ahora, dentro de una carpeta Controllers se crear el controlador democontroller.js el cual será el único controlador para el ejemplo y será el encargado de consumir el servicio creado en el paso anterior.

El cascarón del controlador es:


(function () {
    'use strict';
    angular
        .module('app')
        .controller('democontroller', democontroller);

    democontroller.$inject = ['$scope', 'apiservice'];

    function democontroller($scope, apiservice) {
        $scope.title = 'Demo $resource';
    //Add code
    }
})();

En el controlador se inyecta apiservice, que el servicio que se creo en el paso anterior y da acceso a $resource.

El primer método a implementar es el get que retonar todos los datos, para ello se hace uso del método query, todos los métodos usados por $resource retornan una promise y así en el then manejamos la respuesta si el llamado ha sido correcto, en caso contrario haremos uso del catch, agregando dicha función:


$scope.getAll = function () {
    apiservice.query()
    .$promise
        .then(function (response) { console.log(response) })
        .catch(function (response) { console.log(response); });
};

El siguiente método es para obtener el recurso por su id, acá haremos uso de get(param):


$scope.getOne = function () {
    apiservice.get({id:5})
    .$promise
    .then(function (response) { console.log(response); })
    .catch(function (response) { console.log(response); });
};

Seguimos con la función de crear el recurso, y se debe usar el método save(data), los datos que le pasamos están quemados, pero tú ya te montas el formulario:


$scope.save = function () {
    var data = {
    'name': 'new name',
    'email': 'newname@email.com'
    };
    apiservice.save(data)
    .$promise
    .then(function (response) { console.log(response); })
    .catch(function (response) { console.log(response); });
};

Para el delete, el método es delete(param):


$scope.delete = function () {
    apiservice.delete({id:2})
    .$promise
    .then(function (response) { console.log(response); })
    .catch(function (response) { console.log(response); });
};

Finalmente para actualizar usamos la función que creamos en el apiservice que le dimos el nombre update:


$scope.update = function () {
    var data = {
    'id': '5',
    'name': 'update name',
    'email': 'updatename@email.com',
    };
    apiservice.update(data)
    .$promise
    .then(function (response) { console.log(response); })
    .catch(function (response) { console.log(response); });
};

Al final, el controlador queda:


(function () {
    'use strict';
    angular
        .module('app')
        .controller('democontroller', democontroller);

    democontroller.$inject = ['$scope', 'apiservice'];

    function democontroller($scope, apiservice) {
        $scope.title = 'Demo $resource';
        $scope.getAll = function () {
            apiservice.query()
                .$promise
                    .then(function (response) { console.log(response) })
                    .catch(function (response) { console.log(response); });
        };

        $scope.getOne = function () {
            apiservice.get({id:5})
            .$promise
                .then(function (response) { console.log(response); })
                .catch(function (response) { console.log(response); });
        };

        $scope.save = function () {
            var data = {
                'name': 'new name',
                'email': 'newname@email.com'
            };
            apiservice.save(data)
            .$promise
                .then(function (response) { console.log(response); })
                .catch(function (response) { console.log(response); });
        };

        $scope.delete = function () {
            apiservice.delete({id:2})
            .$promise
                .then(function (response) { console.log(response); })
                .catch(function (response) { console.log(response); });
        };

        $scope.update = function () {
            var data = {
                'id': '5',
                'name': 'update name',
                'email': 'updatename@email.com',
            };
            apiservice.update(data)
            .$promise
                .then(function (response) { console.log(response); })
                .catch(function (response) { console.log(response); });
        };
    }
})();

Y eso es todo! Trabajar con ngResource es realmente sencillo y nos va a ahorrar mucho tiempo.

El código del ejemplo en el siguiente link: Ejemplo en GitHub

Espero el post les sea de utilidad y no te olvides de compartirlo!

Saludos,