¿Qué es un paginador y cómo hacer consultas paginadas en Mat|r script?

Temas: PageFetcher, broker.cloudPersistence.*

El objetivo de este post es que aprendas qué es un paginador y cómo hacer consultas paginadas a una base de datos con métodos de broker.cloudPersistence.*. Veremos un ejemplo en el que se van a mostrar datos paginados a partir de base de datos de supuestos empleados.

Paginador

La paginación es el proceso de dividir contenido, por ejemplo resultados de búsquedas de sitios web, en páginas separadas pero relacionadas entre sí (Figura 1). El beneficio de tal división del contenido es usualmente una estructura más limpia y clara del mismo que mejora la experiencia de lectura (o navegación).


Figura 1. Ejemplo de una base de datos de usuarios paginada. Se muestran 8 usuarios por página.

 

PageFetcher

En mat|r script existe el tipo de dato PageFetcher que crea y configura un elemento paginador que permite administrar una consulta a una colección en forma de páginas. La consulta es definida en un filtro (Filter) que junto con el tamaño de página (pageSize) son parámetros del constructor.

PageFetcher(filter: Filter, pageSize: Integer)

 

 Una vez creada y configurada la instancia del paginador se utiliza como parámetro de los métodos públicos y privados de broker.cloudPersistence.* para obtener las páginas resultantes.

 

Métodos de Cloud Persistence para Consultas Paginadas

Dentro de los métodos que ofrece broker.cloudPersistence.* encontramos los siguientes que hacen uso de PageFetcher para hacer consultas paginadas a una base de datos:

 

Retorna la siguiente página como un arreglo de modelos del tipo especificado en el constructor del filtro, del tamaño especificado al momento de la creación del PageFetcher. Si es la primera vez que se ejecuta, realiza la consulta y devuelve la primera página.

 

Retorna la página anterior como un arreglo de modelos del tipo especificado en el constructor del filtro, del tamaño especificado al momento de la creación del PageFetcher. Si es la primera vez que se ejecuta, realiza la consulta y devuelve la primer página.

 

Reinicia el page fetcher de manera que se realiza nuevamente la consulta y se carga la primera página.

 

Ejemplo: Base de Datos de Empleados

Vamos a acceder a datos de empleados a través de un endpoint de la Rest Api Example (http://dummy.restapiexample.com/) y los vamos a almacenar en la nube mediante Cloud Persistence. Esta es nuestra base de datos. La idea es mostrar los empleados paginados a través de una lista (Figura 2).


Figura 2. Screenshot de la app ejemplo a través del mat|r Viewer. Se muestra la primera página de un total de 147 con 8 elementos.

 

Lógica de la app

 

La Figura 3 define el modelo “Employee” (ver Anexo A):

Figura 3. Definición del modelo “Employee”.

 

Luego, definimos la experiencia “Main” (Figura 4). Esta presenta 4 atributos: “employees” de tipo Array<Employee> asociado a una lista (List); “btnNext” de tipo String asociado a una imagen (Image); “btnPrevious” de tipo String asociado a una imagen (Image); y “paginas” de tipo String asociado a una etiqueta (Label). Las imágenes funcionarán como botones para navegar de una página a otra, mientras que la etiqueta mostrará la página actual que se está mostrando en relación al total de páginas.

Figura 4. Definición de experiencia “Main”.

 

En el bloque “Application” se definen tres variables globales: “pag” de tipo PageFetcher, “exp” de tipo Main y “actualPage” de tipo Integer (Figura 5).

 

Dentro del bloque “OnInit” definimos un filtro “f” y lo inicializamos con su constructor. Le pasamos como argumento el nombre del modelo a filtrar “Employee”. Luego, se inicializa la variable global, el paginador “pag”, con su constructor y le pasamos como argumento el filtro “f” y el tamaño de la página, 8, que es la cantidad de elementos a mostrar por página.


Figura 5. Lógica de inicio de aplicación.

 

Luego inicializamos la experiencia “exp” de tipo “Main” con su constructor. Inmediatamente utilizamos el bloque “try-catch” ya que manejamos código que potencialmente puede lanzar excepciones. Dentro del bloque “try” hacemos la llamada al servicio “getEmployees”, previamente configurado en la sección Endpoints del panel derecho en el Modeller (ver Anexo B). Si la respuesta del servicio fue exitosa y el arreglo es no vacío guardamos la respuesta en la  nube con el método “saveCollection” de cloudPersistence. Ya teniendo una base de datos, luego, podemos obtener esta información para mostrarla en una lista usando “getNextPage” y el paginador ya configurado “pag”.

 

A continuación, Inicializamos las variables “btnNext” y “btnPrevious” con URLs de imágenes que serán los botones para navegar en el paginador. Finalmente, colocamos la experiencia “exp” en la cima de la pila de navegación, inicialmente vacía.

 

Reglas

 

Se definió un contexto de reglas “MainContext” con 2 reglas: “next” y “previous” (Figura 6). Estas son asociadas a las imágenes del layout “btnNext” y de “btnPrevious” respectivamente. Cada vez que tenga lugar el evento de presionar sobre la imagen se mostrarán los 8 elementos siguientes o anteriores utilizando los métodos getNextPage y getPreviousPage respectivamente.

 

La segunda línea actualiza el número de página actual “actualPage” y la siguiente a través de “paginas” muestra en el layout a través de una etiqueta “página actual / páginas totales”.


Figura 6. Lógicas de las reglas “next” y “previous” del “MainContext”.

 

Por último, recuerda que para mostrar los datos, al ser modelos, debes asociar un template en el Build UI a la lista para que puedan ser visualizados.

 

Prueba la app desde el mat|r Viewer escaneando el siguiente código QR:

Podés acceder al código de la app forkeandola desde el siguiente link:

https://platform.matrproject.com/hub/view/5e5548e51c30f500134b5345

 

Anexo A: Respuesta del endpoint de la API

 

Para obtener datos de empleados se utiliza el siguiente endpoint de la Rest Api Example (http://dummy.restapiexample.com/):

 

GET http://dummy.restapiexample.com/api/v1/employees

 

Una respuesta exitosa a la llamada de este endpoint es una estructura JSON del tipo:

 

{“status”:”success”,”data”:[{“id”:”1″,”employee_name”:”Tiger Nixon”,”employee_salary”:”320800″,”employee_age”:”61″,”profile_image”:””},{“id”:”2″,”employee_name”:”Garrett Winters”,”employee_salary”:”170750″,”employee_age”:”63″,”profile_image”:””},..]

 

Dentro del atributo “data” encontramos un arreglo de modelos JSON, cada uno con la información de un empleado: “id”, “employee_name”, “employee_salary”, “employee_age” y “profile_image”. 

 

A partir de esta estructura definimos el modelo con el cual se va a trabajar en la app.

 

Dado que utilizaremos por simplicidad algunas de ellas, definimos el modelo mat|r “Employee” equivalente (Figura 3). Nótese que los tipo de dato de los atributos del modelo “Employee” son de tipo String ya que en el modelo JSON son String. En particular se inicializó “profile” con una URL de una imagen de perfil genérica.

 

Anexo B: Configuración del Endpoint

 

Las figuras 7, 8 y 9 muestran cómo se configuró el endpoint que utiliza esta app ejemplo. El mismo es de http://dummy.restapiexample.com/, la cual ofrece una API Rest online de casos falsos para la prueba de una app.

 

La Figura 7 muestra la sección URL Data, en la cual se completó el nombre del endpoint (Name) “getEmployees”, el método de consulta (HTTP Verb) GET y la URI, http://dummy.restapiexample.com/api/v1/employees. Las secciones Headers y Parameters no requieren de especificar ningún parámetro. 

 

La Figura 8 muestra la sección Response, Response type . Se coloca en Response Type “Array”, Response Root “data” y Response Model “Employee”. 

 

La Figura 9 muestra la sección Response Mapping, donde se debe especificar los atributos del modelo Employee a mapearse con los correspondientes atributos del modelo JSON. Así, colocamos “name” con “name_employee”, “salary” con “empoyee_salary”, “age” con “employee_age” y “profile” con “profile_image”.


Figura 7. Sección URL Data.

 


Figura 8. Sección Response: Response Type.

 


Figura 9. Sección Response: Response Mapping.