es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Error de tipo de React al obtener múltiples puntos finales de la API: TypeError: fetch(…).json no es una función.

Estoy haciendo un proyecto de React.js. Estoy obteniendo datos de una API y los paso desde el componente padre por props. Además, estoy utilizando diferentes puntos finales de la misma API en este componente hijo. Necesito comparar los “personajes” de las props con los que hay en este nuevo punto final de la misma API. Tengo una función que parece funcionar, pero obtengo dos errores. El primero no siempre, pero a veces en la consola muestra un error 429, demasiadas llamadas a la API. Hice una función setTimeOut que parece haberlo solucionado. Pero ahora tengo otro error en el catch que dice: TypeError: fetch(…).json no es una función. Este es el código:

importar estilos desde './MovieDetail.module.css';

const MovieDetail = ({ película }) => {

const personas = película.properties?.characters.map(async (characterURL) => {
    intentar {
        const people = esperar fetch(characterURL).json().results;
        if (people.ok) {
            setTimeOut(() => {
                return people;
            }, 1000)
        };
    }
    capturar (err) {
        console.error('Error personas', err)
    }
})
console.log('personas MovieDetail', personas)

volver (
    <div className={styles.card}>
        <div className={styles.container}>
            <h2>{película.properties?.title}</h2>
            <p>{película.description}</p>
            <p>Fecha de lanzamiento: {película.properties?.release_date}</p>
            <p>Director: {película.properties?.director}</p>
            <p>Productor: {película.properties?.producer}</p>
            <p>Personajes:</p>
            {personas?.map(persona=> (
                <ul id={styles.list}>
                    <li>{persona.properties?.name}</li>
                </ul>
            ))}
        </div>            
    </div>
);

}

exportar por defecto MovieDetail;

Este es todo el código en sandbox.
Gracias de antemano.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución:

    Error 429: Demasiadas llamadas a la API

    El error 429 indica que estamos realizando demasiadas solicitudes a la API en un corto período de tiempo. Para solucionar este problema, podemos usar la función setTimeout para retrasar la ejecución de cada solicitud. En el código proporcionado, podemos ver que ya se ha agregado un retraso de 1000ms a cada solicitud utilizando setTimeout.

    Sin embargo, debemos tener en cuenta que esta es solo una solución temporal y no definitiva. Un enfoque mejor sería almacenar en caché los datos de la API para no tener que realizar llamadas repetidas.

    TypeError: fetch(…).json no es una función

    El error TypeError: fetch(...).json no es una función ocurre porque el método fetch devuelve una promesa que se resuelve en el objeto de respuesta, no en los datos JSON que queremos.

    Para obtener los datos JSON, primero debemos verificar si la respuesta es correcta y luego usar el método json() de la respuesta para extraer los datos.

    Aquí está el código corregido:

    import styles from './MovieDetail.module.css';
    
    const MovieDetail = ({ film }) => {
    
        const fetchData = async (url) => {
            try {
                const response = await fetch(url);
                if (response.ok) { // Verificar si la respuesta es correcta
                    const json = await response.json(); // Extraer datos JSON
                    return json;
                } else {
                    throw new Error('La respuesta de la red no fue correcta.');
                }
            } catch (err) {
                console.error('Error al obtener los datos:', err);
            }
        };
    
        const fetchPeoples = async () => {
            const characterURLs = film.properties?.characters || [];
            const promises = characterURLs.map(url => fetchData(url));
            const peoples = await Promise.all(promises);
            return peoples;
        };
    
        const [peoples, setPeoples] = useState([]);
        useEffect(() => {
            fetchPeoples().then(data => setPeoples(data));
        }, [film.properties?.characters]);
    
        return (
            <div classname="{styles.card}">
                <div classname="{styles.container}">
                    <h2>{film.properties?.title}</h2>
                    {film.description}
                    Fecha de lanzamiento: {film.properties?.release_date}
                    Director: {film.properties?.director}
                    Productor: {film.properties?.producer}
                    Personajes:
                    <ul id="{styles.list}">
                        {peoples.map((people, index) => (
                            <li key="{index}">{people?.result?.properties?.name}</li>
                        ))}
                    </ul>
                </div>            
            </div>
        );
    }
    
    export default MovieDetail;
    

    En el código actualizado, definimos una nueva función fetchData para obtener los datos de la API. Usamos esta función para obtener los datos de cada URL de personaje en la función fetchPeoples utilizando Promise.all para resolver todas las promesas simultáneamente.

    Luego, usamos los hooks useState y useEffect para establecer el estado peoples con los datos obtenidos. Finalmente, recorremos el arreglo peoples para renderizar el nombre de cada personaje en una lista desordenada.

Comments are closed.