Quiero obtener algunos datos de 2 apis, pero necesito algunas propiedades de la primera api para realizar la solicitud de recuperación a la segunda api. También necesito la respuesta completa de la primera API.
export const fetchTrip = createAsyncThunk( 'trip/fetchTrip', async (payload, thunkAPI) => { const result = fetch( 'http://localhost:5000/user/trip/' + payload, { mode: 'cors', credentials: 'include', method: "get", headers: { 'Content-Type': 'application/json' }, }) .then(response => response.json()) .then(data => { const places= data.trips[0].places return Promise.all(places.map(place=> fetch('http://localhost:5000/api/tripadvisor/' + place.id) )) .then(resp => resp.json()) }) console.log(result) return result } )Entonces, la primera solicitud de búsqueda responderá con algunos datos, como
{ title: "Cali Trip", budget: "1000", places: [ {id: "123"}, {id: "234"}, {id: "345"} ] } Estoy usando la id del lugar para obtener más detalles sobre ese lugar. al final, quiero devolver los detalles del viaje de la primera API y todos los detalles de los múltiples lugares de la segunda API. Probé el código anterior, pero mi response no está definida. ty por adelantado para cualquier ayuda!!
Como ya está haciendo que la función sea asíncrona, podría usar await para que sea más fácil de seguir, algo así, solo un boceto para que lo elabore:
export const fetchTrip = createAsyncThunk( 'trip/fetchTrip', async (payload, thunkAPI) => { const data = await fetch('http://localhost:5000/user/trip/' + payload, { mode: 'cors', credentials: 'include', method: 'get', headers: { 'Content-Type': 'application/json', }, }).then((resp) => resp.json()); // here your first result console.log(data); const places = data.trips[0].places; const result = await Promise.all( places.map((place) => fetch('http://localhost:5000/api/tripadvisor/' + place.id).then( (resp) => resp.json() ) ) ); // here the second result console.log(result); // overwrite places with second result return { ...data, places: result, }; } );Esto sería mucho más limpio si no mezclaras async / await .then() .
Lo que puede hacer es devolver la respuesta de la primera solicitud con la matriz de places reasignada con los valores resueltos de las solicitudes secundarias.
export const fetchTrip = createAsyncThunk( "trip/fetchTrip", async (payload, thunkAPI) => { const res = await fetch( `http://localhost:5000/user/trip/${encodeURIComponent(payload)}`, { credentials: "include", // cookies? Do you even need this? } ); if (!res.ok) { // don't forget to check for failures throw res; } // pull out the first "trip" from the "trips" array const { trips: [{ places, ...trip }], } = await res.json(); // respond with the "trip" return { ...trip, // resolve "places" by mapping the array to a new promise // and awaiting its result places: await Promise.all( places.map(async ({ id }) => { const placeRes = await fetch( `http://localhost:5000/api/tripadvisor/${encodeURIComponent(id)}` ); // again, check for errors if (!placeRes.ok) { throw placeRes; } // resolve with the place data return placeRes.json(); }) ), }; } );Parece que está mezclando el código async / await con el código de encadenamiento Promise. Si bien eso es ciertamente válido, si limpiamos un poco su código, puede ver que esto se hace de manera trivial si convierte todo su código a async / await :
const response1 = await fetch('...'); const data1 = await response.json(); const data2 = await Promise.all([...]);Por supuesto, esto se puede hacer con el encadenamiento Promise guardando los datos de las llamadas internas en una variable fuera de las llamadas, pero esa es una opción muy inferior:
let data1; let data2; fetch('...') .then((response) => response.json()) .then((data) => { data1 = data; return Promise.all([...]); })