fetching random json getting first undefined then result - javascript

Beginner on reactjs here, trying to fetch random json, getting the result i want to get, but not the way i want it, for some reason it prints first 'undefined' then after that the result. Why cant i get just the result and without this '?'
my code:
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [thumbnail, setThumbnail] = useState([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/photos")
.then((response) => response.json())
.then((json) => {
setThumbnail(json);
});
}, []);
console.log(thumbnail[0]?.thumbnailUrl);
return (
<div className="App">
<h1>Build</h1>
<p></p>
</div>
);
}
export default App;

console.log() inside App() directly will use the initial state of. thumbnail which is the empty, so it will show undefined.
To check the thumbnail, you should use another useEffect with adding a thumbnail dependency.
useEffect(() => {
if (thumbnail.length > 0) {
console.log(thumbnail[0].thumbnailUrl);
}
}, [thumbnail]);
import { useEffect, useState } from "react";
import "./App.css";
function App() {
const [thumbnail, setThumbnail] = useState([]);
const [isLoaded, setLoaded] = useState(false);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/photos")
.then((response) => response.json())
.then((json) => {
setLoaded(true);
setThumbnail(json);
});
}, []);
useEffect(() => {
if (isLoaded) {
console.log(thumbnail[0]?.thumbnailUrl);
}
}, [thumbnail]);
return (
<div className="App">
<h1>Build</h1>
<p></p>
</div>
);
}
export default App;

While the response of your http does not come, you can simply render a loading component (a text in this example), then when thumbnail state changes, React will re-render your component and update it with the new data.
Just a working example:
import React, { useEffect, useState } from "react";
import "./App.css";
function App() {
const [thumbnail, setThumbnail] = useState([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
fetch("https://jsonplaceholder.typicode.com/photos")
.then((response) => response.json())
.then((json) => {
setThumbnail(json);
})
.finally(() => {
setIsLoading(false);
});
}, []);
return (
<div className="App">
<h1>Build</h1>
{isLoading ? (
<h3>Loading...</h3>
) : (
thumbnail.map((item) => {
return <span key={item.id}>{item.title}</span>;
})
)}
</div>
);
}
export default App;

Related

data.map is not a function in react all api

I'm trying to call simple apiCall in react js but this is giving error as given below:-
data.map is not a function
SandBox Url:-
My Code:-
import "./styles.css";
import React, { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState();
const apiCall = () => {
fetch("https://fakestoreapi.com/products/1")
.then((res) => res.json())
.then((json) => {
setData(json);
console.log(data);
});
};
useEffect(() => {
apiCall();
}, []);
return (
<div className="App">
{data
? data.map((val) => (
<div>
<h2>{val.id}</h2>
</div>
))
: ""}
</div>
);
}
Thanks for your efforts!
Because the data return from API is an Object, and there is no map method for the object, you can use Object.entries, Object.values, Object.keys to iterate over an object.
import "./styles.css";
import React, { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState();
const apiCall = () => {
fetch("https://fakestoreapi.com/products/1")
.then((res) => res.json())
.then((json) => {
setData(json);
});
};
console.log(data);
useEffect(() => {
apiCall();
}, []);
return <div className="App">{
data ? Object.entries(data).map(([key, value]) => <div><span>{ key }:</span><span>{ JSON.stringify(value) }</span></div>) : null
}</div>;
}
The data you're getting from https://fakestoreapi.com/products/1 is an object, not array. You cannot only apply map method on an Object. Read about map here
I edit your code to :
you get this error because data is a object not an array
import "./styles.css";
import React, { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState();
const apiCall = () => {
fetch("https://fakestoreapi.com/products/1")
.then((res) => res.json())
.then((json) => {
setData(json); // json is object not array
console.log(data);
});
};
useEffect(() => {
apiCall();
}, []);
console.log(data);
if (data) {
return (
<div className="App">
<div>
<h2>{data.id}</h2>
</div>
</div>
);
} else {
return <></>;
}
}

Why can't I render multiple cards using map?

I'm trying to render multiple cards by pulling data from the API. But the return is an array, I don't understand why the map is not working.
const CharacterCard = () => {
const [showModal, setShowModal] = useState(false)
const openModal = () => {
setShowModal(prev => !prev)
}
const characters = useRequestData([], `${BASE_URL}/characters`)
const renderCard = characters.map((character) => {
return (
<CardContainer key={character._id} imageUrl={character.imageUrl}/>
)
})
return (
<Container>
{renderCard}
<ModalScreen showModal={showModal} setShowModal={setShowModal} />
</Container>
)
}
export default CharacterCard
The hook is this
import { useEffect, useState } from "react"
import axios from "axios"
const useRequestData = (initialState, url) => {
const [data, setData] = useState(initialState)
useEffect(() => {
axios.get(url)
.then((res) => {
setData(res.data)
})
.catch((err) => {
console.log(err.data)
})
}, [url])
return (data)
}
export default useRequestData
console error image
requisition return image
API: https://disneyapi.dev/docs
Looks like the default value of the characters is undefined.
So something like (characters || []).map.. will help I think.
For deeper look at this you can debug useRequestData hook, as I can't see the source of that hook from you example

React native Pull to refresh is not working

I m trying to add pull to refresh to fetch my data from my api but it is not working and i can'y find the problem within the code:
const[refresh,setRefresh]=useState(true)
const onRefresh=()=>{
try{
axios
.get('http://192.168.1.17:8000/File/')
.then((response)=> {
setFile(response.data);
setFilteredFile(response.data)
setEmpty(false)
setRefresh(false);
})}
catch(error){console.log(error)
}
}
useEffect(()=>{
onRefresh()
},[])
<FlatList style={DocumentStyle.flatstyle}
keyExtractor={(item)=>item['id']}
data={filteredfile}
renderItem={renderItem}
onRefresh={()=>onRefresh()}
refreshing={refresh}
/>
never mind me everyone, i haven't set my refresh back to true after the useEffect set it to false
The error is due to not importing useState, but you also need to import useEffect. I also dont see where some of the props your passing to FlatList are being used. But here's a working sample:
import {useState, useEffect} from 'react';
const FlatList = ({file, refreshing, onRefresh}) => {
return (
<div>
<p>{file}</p>
<button onClick={() => onRefresh(2)}>Load another todo</button>
</div>
)
}
export default function App() {
const [refresh, setRefresh] = useState(true);
const [file, setFile] = useState('');
useEffect(() => onRefresh(), []);
const onRefresh = (id=1) => {
try {
fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
.then(response => response.json())
.then(json => {
console.log(json)
setFile(JSON.stringify(json))
setRefresh(false);
})
}
catch(error) {
console.log(error);
}
}
return <FlatList file={file} refreshing={refresh} onRefresh={onRefresh} />
}

API giving data in second render in React

I was trying to fetch api with react.js but on first render its gives nothing and the second render its gives data. This makes it so when I try to access the data later for an image I get an error, TypeError: Cannot read property 'news.article' of undefined, because it is initially empty. how can I solve this?
here is my code ..
import React, { useEffect, useState } from 'react';
const HomeContent = () => {
const [news, updateNews] = useState([]);
console.log(news);
useEffect(() => {
const api = 'http://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=940c56bd75da495592edd812cce82149'
fetch(api)
.then(response => response.json())
.then(data => updateNews(data))
.catch((error) => console.log(error))
}, [])
return (
<>
</>
);
};
export default HomeContent;
There is no issue with the code itself, the output you receive is expected. However, you can render the content after it is retrieved as such
import React, { useEffect, useState } from 'react';
const HomeContent = () => {
const [news, updateNews] = useState([]);
const [isLoading, setIsLoading] = useState(true);
console.log(news);
useEffect(() => {
const api = 'http://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=940c56bd75da495592edd812cce82149'
fetch(api)
.then(response => response.json())
.then(data => {
updateNews(data.articles);
setIsLoading(false);
})
.catch((error) => {
console.log(error);
setIsLoading(false);
})
}, [])
return (
<>
{isLoading ?
<p>Loading...</p> :
// Some JSX rendering the data
}
</>
);
};
export default HomeContent;

How to render a list from a JSON url? - ReactJS hooks

I want to render a list from a JSON URL. However, I have the following error: Objects are not valid as a React child (found: TypeError: Failed to fetch). If you meant to render a collection of children, use an array instead. What am I going wrong? Thanks for your answer
//hooks.tsx
import { useEffect, useState } from 'react'
export const useFetch = () => {
const [data, setData] = useState([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
useEffect(() => {
setLoading(true)
setError(null)
fetch('https://jsonkeeper.com/b/Z51B')
.then(res => res.json())
.then(json => {
setLoading(false)
if (json.data) {
setData(json.data)
} else {
setData([])
}
})
.catch(err => {
setError(err)
setLoading(false)
})
}, [])
return { data, loading, error }
}
//index.tsx
import React from 'react';
import { useFetch } from "./hooks.js";
import {CardItem} from './card';
export const List = () => {
const { data, loading, error } = useFetch()
if (loading) return <div>Loading...</div>
if (error) return <div>{error}</div>
return (
<>
<ul>
{data.map((item: any, index: any) => (
<li key={index}>
{item.names.map((name: any) => {
return <CardItem
family={item.family}
name={name}
/>
})
}
</li>
))}
</ul>
</>
);
};
I guess the problem is with your setError(err) in catch block of your custom hook. It should be setError(err.message).

Categories

Resources