# Servicios

La capa de datos en una aplicación Ionic o Angular se encarga de proporcionar, como su propio nombre indica, los datos desde un almacenamiento local o desde un servicio externo. Esta capa de datos la proporcionan las clases conocidas como *Servicios* o *Factories*. Ambas clases son muy similares y nos referiremos a ellas como capa o clase de datos. La diferencia estriba en el valor devuelto, los servicios siempre tienen que devolver un objeto (ya que al inyectarlos se les llamará con `new`), mientras que los *Factories* son más versátiles y podrán devolver lo que queramos ya que simplemente se ejecutará la función que lo define.

Como hemos visto el proceso seguido en una petición es el siguiente: El controlador solicita los datos a la capa de datos para prepararlos y pasárselos a la vista. La capa de datos normalmente definirá una serie de métodos para el acceso a los datos. A continuación se incluye un ejemplo sencillo de una capa de datos:

```javascript
.factory('superService', function() {
    return {
        getUser: function() {
            var user = { name: "Juan" };
            return user;
        },
    }
})
```

En este caso el servicio `superService` define un único método `getUser()` que devolverá un objeto con el nombre del usuario. Siguiendo este esquema podemos añadir todos los métodos que queramos al servicio y definir una API de consulta.

Para usar un servicio desde un controlador en primer lugar hay que solicitarlo en los parámetros para que Angular lo inyecte. Posteriormente, desde dentro del código de la función ya lo podemos usar y acceder a los valores o funciones que hayamos definido en la clase de datos:

```javascript
.controller('MiSuperControladorCtrl', function($scope, superService) {
    $scope.user = superService.getUser();
})
```

## Consultas asíncronas

En el ejemplo anterior los datos estaban guardados en una variable, pero lo más común es que tengamos que consultar esos datos desde un servicio remoto o desde una base de datos. Si utilizamos un servicio que pueda tardar en devolver la respuesta tendremos que trabajar de forma asíncrona para no bloquear la aplicación.

Al realizar una petición asíncrona la función del servicio no podrá devolver el valor directamente, sino que usará la función `then` para ayudarnos con la respuesta asíncrona. Por ejemplo, para hacer una consulta HTTP a una API externa y devolver la respuesta podríamos escribir el siguiente código en el servicio:

```javascript
.factory('superService', function($http) {
    return {
        getUser: function() {
              return $http.get("url-de-consulta").then(function(response) {
                    //...
                    return response;
              });
        },
    }
})
```

Dentro de la función `then` podemos procesar los datos obtenidos y después devolver la respuesta. Para usar este servicio desde un controlador lo realizaremos como en el ejemplo anterior: solicitamos que el servicio se inyecte en los parámetros, llamamos al método de forma normal `superService.getUser()` pero la respuesta la tenemos que procesar con la función `then`. Esta función lo que hará es **quedarse esperando** a recibir la respuesta y una vez obtenida se ejecutará la función asignada como primer parámetro:

```javascript
.controller('MiSuperControladorCtrl', function($scope, superService) {
    superService.getUser().then(function(response){
        $scope.user = response;
    });
})
```

Además podemos asignar un segundo parámetro a la función `then` que será otra función *callback* que se llamará cuando la petición al servicio o la respuesta fallen.

## Más información

Para más información podéis consultar:

* <https://docs.angularjs.org/api/ng/service/$q>
* <http://mcgivery.com/ionic-using-factories-and-web-services-for-dynamic-data/>&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ajgallego.gitbook.io/ionic/arquitectura/arquitectura_servicios.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
