how to fetch data from Api folder in next.js - api

I"m facing this problem, I store my submitted data in api folder from a page and i successfully can store it and when i console.log it I can see the data but the problem is when I try fetch it to a page where I want show all this data then I didn't get any result, it's shows empty object:
this is the page from where I submitted data to api folder/page
const handleSubmitAllData = async (e) => {
e.preventDefault();
const allData = {
addStory,
selectedVideoUrl,
};
console.log("AllNftData:", allData);
try {
const { data } = await axios({
url: "/api/uploadNftData",
method: "POST",
data: allData,
});
console.log("response Data", data);
} catch (error) {
console.log("Error", error);
}
router.push("/template/marketplace");
};
this is the api page where store data, when console.log the data i see it that's means it's working
this is code of api page
const { log } = console;
export default function teamAdd(req, res) {
if (req.method === "POST") {
const nftData = req.body;
log("Req payload", nftData);
res.json(nftData);
}
return res.status(500).json({
msg: "this needs to be post request",
});
}
and this is page where I try to fetch this store data from api. this is code , it's not working. I try so many time but it's always comes out with not data
function page() {
const [data, setData] = useState(null);
const [isLoading, setLoading] = useState(false);
const [comments, setComments] = useState([]);
const fetchComments = async () => {
const response = await fetch("/api/uploadNftData");
const data = await response.json();
setComments(data);
console.log(data);
};
useEffect(() => {
setLoading(true);
fetch("/api/uploadNftData", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({}),
})
.then((res) => {
console.log(res);
return res.json();
})
.then((data) => {
console.log(data);
setData(data);
setLoading(false);
})
.catch((error) => {});
}, []);
if (isLoading) return <p>Loading...</p>;
if (!data) return <p>No profile data</p>;
return (
<>
<Main>
<Templatepage>
<TemplateHeader />
<Herosec>
marketplace
<Box
sx={{
background: "#000",
height: "200px",
width: "200px",
margin: "80px",
}}
>
<h1 style={{ color: "#fff" }}>{data.addStory}</h1>
<p style={{ color: "#fff" }}>{data.selectedVideoUrl}</p>
</Box>
</Herosec>
</Templatepage>
</Main>
</>
);
}

What happens if you try to update the dependency array of the useEffect with data
useEffect(() => {
setLoading(true);
fetch("/api/uploadNftData", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({}),
})
.then((res) => {
console.log(res);
return res.json();
})
.then((data) => {
console.log(data);
setData(data);
setLoading(false);
})
.catch((error) => {});
}, [data]);
And I would change the default state of
const [data, setData] = useState(null);
to something more reliable like some custom interface or type.

You can try to verify if data is null in useEffect and then do the request.
It should look something like this:
useEffect(() => {
if(data === null){
setLoading(true);
fetch("/api/uploadNftData", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({}),
})
.then((res) => {
console.log(res);
return res.json();
})
.then((data) => {
console.log(data);
setData(data);
setLoading(false);
})
.catch((error) => {});
}
}, [data]);

Related

why passing params do not refresh and have to refresh the new page update

i am trying to pass params to next page by calling id from previous
page. but when you enter the next page the data does not appear
immediately and you have to refresh the page which takes quite a long
time, and faithfully calling new data, what appears is the previous
data, you have to refresh the page to bring up new data. what is the
solution?
first page code
...//
onPress={() => {
setId(item.ID);
navigation.navigate('Rekap_Bencana', {
params: id
});
}}
...//
const [dataBencana, setDataBencana] = useState();
const [id, setId] = useState();
useEffect(() => {
getData();
}, []);
const getData = () => {
fetch('http://192.168.0.103/aplikasi/restapi.php?op=getDatabencana')
.then(response => response.json())
.then(json => {
// console.log(json);
setDataBencana(json);
// console.log(dataBencana);
});
};
params page code
const Rekap_Bencana = () => {
const route = useRoute();
const navigation = useNavigation();
const {params} = route.params;
useEffect(() => {
getData();
console.log(params);
}, []);
const [data, setData] = useState();
const getData = () => {
fetch('http://192.168.0.103/aplikasi/restapi.php?op=getBencanaDetail', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: params,
}),
})
.then(res => res.json())
.then(resp => {
setData(resp);
console.log(resp);
});
};

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop React Native with FlatList render

I don't understand why I get this error, when rendering screen I use useSelector to get state from store(I'm using redux) I get data from api and pass it to flatList to render the list, everything is normal but I don't know why
const HistoryScreen = () => {
const { loading, histories } = useSelector((state) => state.historiesList)
useEffect(() => {
if (user) {
dispatch(listHistory())
}
}, [dispatch, user])
return (
<FlatList data={histories} renderItem={({ item, i }) => <HistoryCard key={i} onPress={() => console.warn('cliecked')} post={item} ></HistoryCard>}>
</FlatList >
</View >}</>
)
}
export default HistoryScreen
action:
export const listHistory = (skip = 0, limit = 10) => async (dispatch, getState) => {
try {
dispatch({ type: HISTORY_LIST_REQUEST })
const user = await AsyncStorage.getItem('userInfo')
const userInfo = user ? JSON.parse(user) : null
const config = {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${userInfo.token}`
}
}
const payload = { skip: skip, limit: limit }
const { data } = await axios.post(`${api}/histories/`, payload, config)
dispatch({ type: HISTORY_LIST_SUCCESS, payload: data.data })
console.log(data.data)
} catch (error) {
dispatch({ type: HISTORY_LIST_FAILED, payload: error })
}
}

How to upload a file in react-native iOS?

While trying to upload a file I ran into an issue on iOS, the code works fine on android. After a bit of googling, I found that it is a known issue in react-native iOS and has a bug report submitted. This is the issue. I want to know if there is any other way to upload files on iOS. Below is the snippet of code I'm using. Please let me know if there is something that can be done.
const resp = await fetch(uploadUrl, {
method: 'POST',
headers: {
'content-type': 'multipart/form-data',
},
body: file, // file is File type
});
You can something like below code snippet
function uploadProfileImage(image, token) {
const url = ServiceUrls.UPLOAD_PROFILE_IMAGE
return uploadResourceWithPost({
url,
authToken: token,
formData: createFormData(image),
})
}
const createFormData = (data) => {
const form = new FormData()
form.append('file', {
uri: Platform.OS === 'android' ? data.uri : data.uri.replace('file://', ''),
type: 'image/jpeg',
name: 'image.jpg',
})
return form
}
const uploadResourceWithPost = ({ url, authToken, formData }) => {
return handleResponse(axios.post(url, formData, defaultUploadOptions(authToken)))
}
const defaultUploadOptions = (authToken) => ({
timeout,
headers: {
'X-Auth-Token': authToken,
'Content-Type': 'multipart/form-data',
},
})
const handleResponse = (responsePromise) => {
return NetInfo.fetch().then((state) => {
if (state.isConnected) {
return responsePromise
.then((response) => {
return ResponseService.parseSuccess(response)
})
.catch((error) => {
return ResponseService.parseError(error)
})
}
return {
ok: false,
message: 'Check your network connection and try again.',
status: 408,
}
})
}
const parseSuccess = ({ data, headers }) => ({ ...data, headers, ok: true })
const parseError = ({ response }) => {
let message = 'Check your network connection and try again.'
let status = 408
if (response && response.data) {
const { data } = response
message = data.message
status = data.code
}
return { status, message }
}

Await is only allowed within async functions error react native

I am new to react native and trying to save user obejct in application storage using await AsyncStorage.setItem('user', res[1].data); However I am getting error as
handleLogin = async() => {
NetInfo.fetch().then(state => {
if (state.isConnected) {
const {navigate} = this.props.navigation;
const data = {
email: this.state.userName,
password: this.state.password
};
fetch(`${DOMAIN_URL}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then((response) => {
const statusCode = response.status.toString();
const data = response.json();
return Promise.all([statusCode, data]);
})
.then((res) => {
if (res[0] == 200) {
await AsyncStorage.setItem('user', res[1].data);
navigate('Home');
}else{
Alert.alert(
res[1].message
);
}
})
.catch((error) => {
console.error(error);
});
}
else {
Alert.alert(
"No Internet!",
"Needs to connect to the internet in order to work. Please connect tablet to wifi and try again.",
[
{
text: "OK",
onPress: () => { }
}
]
);
};
})
};
I have made the handleLogin async but it doesn't solve the error. What is the correct way to store user obejct?
It is recommended that you use react-native-easy-app , through which you can access any data in AsyncStorage synchronously.
Sample_Hooks
StorageController
navigateToHome = async (user) => {
const { navigate } = this.props.navigation;
await AsyncStorage.setItem('user', user);
navigate('Home');
}
handleLogin = async() => {
NetInfo.fetch().then(state => {
if (state.isConnected) {
const data = {
email: this.state.userName,
password: this.state.password
};
fetch(`${DOMAIN_URL}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then((response) => {
const statusCode = response.status.toString();
const data = response.json();
return Promise.all([statusCode, data]);
})
.then((res) => {
if (res[0] == 200) {
navigateToHome(res[1].data);
}else{
Alert.alert(
res[1].message
);
}
})
.catch((error) => {
console.error(error);
});
}
else {
Alert.alert(
"No Internet!",
"Needs to connect to the internet in order to work. Please connect tablet to wifi and try again.",
[
{
text: "OK",
onPress: () => { }
}
]
);
};
})
};

Getting JSON info from API

I'm using Axios(Apisauce) to connect API to React Native App;
this is the JSON file I'm trying to show in-app using FlatList :
{
"data": {
"sideMenu": {
"url": "https://google.com",
"icons": [
{
"id": 1,
"url": "https://google.com",
"status": 1
},
]
},
}
}
when I try to log it into the console, using console.log(response.data) returns all API info, but using console.log(response.data.data) doesn't return the object I'm looking for!
I've tried JSON.stringify() or toString() but none of them seem to Work.
my Axios Code :
const getServices = () => {
const service = "https://api.team-grp.ir/app/json/services2.json/";
return client.get(service);
};
My Source Code:
const ServiceInfo = async () => {
await getServices()
.then((response) => {
if (response.ok) {
setServicesData(response.data.data);
}
})
.catch((error) => {
console.warn(error);
setServicesData([]);
});
};
useEffect(() => {
ServiceInfo();
});
you should not use async/await with .then/.cache ...
this code is working for me:
(you can also see my sample code image at the bottom of this answer with a fake getService function, and you will see that logged response is correct)
const ServiceInfo = () => {
getServices().then((response) => {
if (response.ok) {
setServicesData(response.data.data);
}
})
.catch((error) => {
console.warn(error);
setServicesData([]);
});
};
useEffect(() => {
ServiceInfo();
}, []);
const ServiceInfo = async () => {
await getServices()
.then((response) => {
return response.json();
})
.then((response) => {
setServicesData(response.data);
})
.catch((error) => {
console.warn(error);
setServicesData([]);
});
};
Try this