Estoy colocando mis llamadas API en una nueva función para poder llamarlas fácilmente con un par de líneas en lugar de una tonelada de código en cada página. El problema que tengo es que la sincronización y la espera se completan antes de devolver los datos.
Obtengo console.log(sess.getIdToken().getJwtToken()) consolado primero, seguido de undefined para console.log(getMessages), luego los datos de console.log(response).
Entonces, await Auth.currentSession().then(...) se ejecuta pero no espera la llamada axios dentro de él. ¿Cómo devuelvo los datos para poder acceder a ellos en el useEffect?
useEffect(() => { async function getMessages() { const getMessages = await ApiService.getMessages(); console.log(getMessages) } getMessages(); }, []); async getMessages() { return await this.__sendRequest("/default/message", "GET"); } async __sendRequest(url, method) { await Auth.currentSession().then(sess => { console.log(sess.getIdToken().getJwtToken()) axios({ method: method, url: process.env.REACT_APP_USER_URL + url, headers: { "X-TOKEN-ID": sess.getIdToken().getJwtToken(), "addresseeType": "P", "content-type": "application/json" } }).then(function (response) { console.log(response) return response }).catch(err => { console.error(err); }) }) }Mezclar async/await await con el encadenamiento de promesas ( .then(...) ) es una manera realmente fácil de complicar demasiado su código.
Puedo ver un par de lugares que contribuyen a que esto no funcione.
__sendRequest no está devolviendo nada..then te falta un retorno.Aquí hay un código simplificado y fijo.
async __sendRequest(url, method) { const sess = await Auth.currentSession() console.log(sess.getIdToken().getJwtToken()) const response = await axios({ method: method, url: process.env.REACT_APP_USER_URL + url, headers: { "X-TOKEN-ID": sess.getIdToken().getJwtToken(), "addresseeType": "P", "content-type": "application/json" } }) console.log(response) return response } Verifique los comentarios de la otra respuesta, para comprender acerca de async/await , devolución y pila de llamadas https://stackoverflow.com/a/69179763/1728166
Hay un par de problemas:
__sendRequest no tiene return , por lo que cuando termine de esperar, cumplirá su promesa con undefined .Auth.currentSession() no espera que la llamada axios se complete porque las dos cadenas no están vinculadas de ninguna manera. Además, en general, no mezcle usando .then / .catch con async / await , no hay necesidad (generalmente); solo usa await :
useEffect(() => { async function getMessages() { try { const getMessages = await ApiService.getMessages(); console.log(getMessages); } catch (error) { // ...*** handle/report error... } } getMessages(); }, []); async getMessages() { return await this.__sendRequest("/default/message", "GET"); } async __sendRequest(url, method) { const sess = await Auth.currentSession(); console.log(sess.getIdToken().getJwtToken()); return await axios({ method: method, url: process.env.REACT_APP_USER_URL + url, headers: { "X-TOKEN-ID": sess.getIdToken().getJwtToken(), "addresseeType": "P", "content-type": "application/json" } }); }getMessages() es asíncrono, por lo que debe llamar con await y hacer que la función de devolución de llamada de la primera línea sea asíncrona para que pueda usar await dentro de ella.
useEffect(async () => { async function getMessages() { const getMessages = await ApiService.getMessages(); console.log(getMessages) } await getMessages(); }, []);puede simplificar __sendRequest convirtiendo todas las devoluciones de llamada de then() en espera y colocando toda la cadena dentro de un bloque de prueba/captura.