Llamadas a servicios REST
Para hacer las llamadas al backend utilizaremos el paquete Axios. En nuestro proyecto tendremos una carpeta services con los archivos Javascript que contengan los servicios. Un ejemplo podría ser el siguiente. Nos definimos un archivo endpoints.js para tener las URLs a las que se llamarán:
...
El objeto que obtenemos al hacer las llamadas a la API es de tipo Promise. Podemos consultar esta página para entender cómo funciona este tipo de dato, y las opciones que tenemos para gestionar la respuesta obtenida, que pasamos a ver cómo funciona.
Promesas (Promise) en JavaScript
En el desarrollo de aplicaciones FundewebJS vamos a tener que lidiar con el tipo de dato Promise de JavaScript, sobre todo en las llamadas a APIs REST. Los objetos Promise se inicializan, ejecutan una tarea y se resuelven (o se rechazan):
Este proceso se ejecuta de forma asíncrona, es decir, una vez se crea el objeto Promise, el código seguirá ejecutándose independientemente de que se la tarea de la Promise haya finalizado o no. Esto, en llamadas a servicios REST se traduce en que enviamos la petición al servidor y, antes de haber obtenido una respuesta, se sigue ejecutando el código.
Consumir objetos Promise
En el caso mencionado, actuaremos como consumidores de un objeto Promise que nos dará la llamada a la API REST, por lo tanto lo que haremos será reaccionar al resultado obtenido, estableciendo las funciones con .then, .catch y .finally, que nos resultará familiar si hemos desarrollado con otros lenguajes de progamación, como Java.
.then
El método más importante es .then, donde especificaremos el código a ejecutar en el momento en el que la promesa se resuelva o se rechace. Tendrá la siguiente sintaxis:
| Bloque de código | ||
|---|---|---|
| ||
promise.then(
function(result) { /* Código en respuesta a un resultado exitoso */ },
function(error) { /* Código en respuesta a un error */ }
); |
O de forma abreviada:
| Bloque de código | ||
|---|---|---|
| ||
promise.then(
(result) => { /* Código en respuesta a un resultado exitoso */ },
(error) => { /* Código en respuesta a un error */ }
); |
El primer argumento define la función que se ejecutará en el momento en el que se resuelva la promesa, y el segundo argumento la función que se ejecutará si se devuelve un error. Si solo estamos interesados en reaccionar a una respuesta exitosa, podemos indicar únicamente el primer argumento.
.catch
Si estamos interesados únicamente en reaccionar los errores, podemos utilizar .then(null, funcion), o podemos utilizar .catch(funcion), que haría exactamente lo mismo:
| Bloque de código | ||
|---|---|---|
| ||
promise.catch((error) => { /* Código en respuesta a un error */ }); |
.finally
Por último, la función que indiquemos en el .finally se ejecutará después de que la promesa haya dado un valor, ya sea un valor correcto o un error, y su sintaxis sería la siguiente:
| Bloque de código | ||
|---|---|---|
| ||
promise.finally(() => { /* Código */ }); |
Una prticularidad del .finally es que no tiene por qué ser el último trozo de código que se ejecute. Todos estos métodos se ejecutan una vez haya finalizado la promesa, la diferencia es que .finally no recibe ningún argumento; no sabe si la finalización ha sido exitosa o no. Poniéndolo antes de .then o .catch, su código se ejecutará antes:
| Bloque de código | ||
|---|---|---|
| ||
promise.finally(() => alert("Promesa lista").then(result => alert(result));
promise.finally(() => alert("Promesa lista").catch(err => alert(err)); |
Crear objetos Promise
Aunque en nuestro caso será menos necesario, también es importante conocer cómo se crean los objetos Promise. La sintaxis del constructor de un objeto promise sería la siguiente:
| Bloque de código | ||
|---|---|---|
| ||
let promise = new Promise(function(resolve, reject) {
// executor (el código que ejecutará la Promise)
}); |
La función que se le pasa al new Promise se llama executor, que se ejecuta automáticamente cuando se crea la Promise, y producirá el resultado. Esta función devuelve un resultado llamando a uno de estos dos callbacks:
resolve(value)- si la tarea ha finalizado con éxito, devolviendovalue.reject(error)- si se ha producido un error, devolviendo el objetoerror.
