I have a function apiFunction inside the useEffect, which make request to the server:
useEffect(() => {
async function fetchData(currentPage, searchInput ) {
try {
const res = await apiFunction ('api/categories', { method: 'GET'}, currentPage, searchInput);
setValue(prev => ({
...prev,
listCategory: res.data,
currentPage: res.page,
buttonsPagination: Math.ceil(res.total / res.perPage)
}));
} catch (e) {
console.error(e);
}
}
fetchData(value.currentPage, value.searchInput);
}, [value.currentPage, value.searchInput]);
Function apiFunction is in a separate file and looks like this:
export const apiFunction = async (url, args, valuePage) => {
const response = await fetch(`${apiUrl}${url}?page=${valuePage}&q=${valueFilter}`, {
...args,
headers: {
"Content-type": "application/json; charset=UTF-8 ",
"Accept": 'application/json',
...args.headers,
},
});
return response.json();
}
This function was created simply for convenience. But now I dont need this function. I need that code from apiFunction was inside function fetchData. That is, that the function apiFunctiondid not exist at all.
How to implement it?
You can simply replace the apiFunction with fetch call in your component like below
useEffect(() => {
async function fetchData(currentPage, searchInput) {
try {
const resJson = await fetch(`${apiUrl}api/categories?page=${currentPage}`, {
method: 'GET'
headers: {
"Content-type": "application/json; charset=UTF-8 ",
Accept: "application/json",
}
});
const res = await resJson.json();
setValue(prev => ({
...prev,
listCategory: res.data,
currentPage: res.page,
buttonsPagination: Math.ceil(res.total / res.perPage)
}));
} catch (e) {
console.error(e);
}
}
fetchData(value.currentPage, value.searchInput);
}, [value.currentPage, value.searchInput]);
Related
I made this custom hook.
import axios from "axios";
import Cookies from "js-cookie";
import React from "react";
const useGetConferList= () => {
let token = JSON.parse(localStorage.getItem("AuthToken"));
const Idperson = JSON.parse(Cookies.get("user")).IdPerson;
const [response, setResponse] = React.useState();
const fetchConfer= (datePrensence, idInsurance, timePrensence) => {
axios({
method: "post",
url: `${process.env.REACT_APP_API_URL_API_GET_ERJASERVICE_LIST}`,
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
data: JSON.stringify({
datePrensence,
idInsurance,
Idperson,
searchfield: "",
timePrensence: parseInt(timePrensence) * 60,
}),
})
.then((r) => {
setResponse(r.data.Data);
})
.catch(() => alert("NetworkError"));
};
return { fetchConfer, response };
};
export default useGetConferList;
as you can see I export the fetchConfer function. but I want to make it async. for example, calling the function and then doing something else like this:
fetchConfer(Date, Time, Id).then((r) => {
if (search !== "") {
window.sessionStorage.setItem(
"searchList",
JSON.stringify(
r.data
)
);
}
});
as you can see in non async situation, I can't use then.
You can try this
const fetchConfer = async (datePrensence, idInsurance, timePrensence) => {
try {
const response = await axios({
method: "post",
url: `${process.env.REACT_APP_API_URL_API_GET_ERJASERVICE_LIST}`,
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
data: JSON.stringify({
datePrensence,
idInsurance,
Idperson,
searchfield: "",
timePrensence: parseInt(timePrensence) * 60,
}),
})
setResponse(response.data.Data);
// need to return data
return response.data.Data
} catch(error) {
alert("NetworkError")
}
};
use the function in another async function
const someAsyncFunc = async () => {
// try catch
const r = fetchConfer(Date, Time, Id)
if (search !== "") {
window.sessionStorage.setItem(
"searchList",
JSON.stringify(
r.data
)
);
}
...
or use it how you are currently using it
Hope it helps
Initially I write my code with promise based script .then().catch
But when I tried to change it into the async await function. Its not working anymore.
Please someone help me with this.
My Old Code Which is working
export const fetchToken = (params) => {
return (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
return axios
.post(`/api/token`, params, config)
.then((res) => {
tokenData = res.data.access_token;
dispatch({
type: LOGGED_IN,
payload: res.data,
});
})
.catch((err) => {
console.log(err);
alert('Provided username and password is incorrect');
throw err;
});
};
};
As you can see in the above code the function is returning a promise. But When I try to change it into async await
My simulator is give me Unexpected reserved work await Error
Here is my async await code in redux
export const fetchToken = async (params) => {
return (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
try {
const response = await axios.post(`/api/token`, params, config);
const data = await response.json();
tokenData = data.access_token
dispatch({ type: LOGGED_IN, payload: res.data})
} catch {
console.log(err);
alert('Provided username and password is incorrect');
}
};
};
Your async is applied to the wrong function, it should be on the dispatch function
export const fetchToken = (params) => (
async (dispatch) => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
try {
const response = await axios.post(`/api/token`, params, config);
const data = await response.json();
tokenData = data.access_token
dispatch({ type: LOGGED_IN, payload: res.data})
} catch {
console.log(err);
alert('Provided username and password is incorrect');
}
};
);
NB: I've removed the braces; arrow function return is implied https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
I need a way to make a request with method Post passing a body but I didnt find a way to do it. The documentation: https://docs.expo.io/versions/latest/sdk/filesystem/ only show the GET method, I need a way to make a post request passing the body.
FileSystem.downloadAsync(${baseUrl}/v1/paycheck/pdf, FileSystem.documentDirectory + ‘file.pdf’,
{
headers: {
‘Authorization’: localToken
},
httpMethod: ‘POST’,
body: {
type: 'monthy',
year: '2021',
month: 2,
employer: {
name: "Pink",
}
}
}
)
.then(({uri}) => {
Sharing.shareAsync(uri, {dialogTitle: 'Salvar ou Compartilhar'})
})
.catch(error => {
console.error(error);
});
}
As far as I understand your problem
My Approach for Downloading and Sharing the PDF would be
Writing these two functions
// Execute this function when you to share the file...
const GetPDF = async () => {
try {
const response = await fetch(`${baseUrl}/v1/paycheck/pdf`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: "localToken",
},
body: JSON.stringify({
type: "monthy",
year: "2021",
month: 2,
employer: {
name: "Pink",
},
}),
});
const content = await response.json();
DownloadThenShare(content); // Some URI
} catch (error) {
console.error(error);
}
};
Now DownloadAndShare function
// This function will execute after Download has been completed successfully
const DownloadThenShare = async (uri) => {
const downloadInstance = FileSystem.createDownloadResumable(
uri,
FileSystem.documentDirectory + "file.pdf"
);
const result = await FileSystem.downloadInstance.downloadAsync();
if (result.status === 200) {
Sharing.shareAsync(result.uri, { dialogTitle: "Salvar ou Compartilhar" });
} else {
console.log("Failed to Download");
}
};
I finally managed to make it work using axios e FileReader();
const response = await axios.post(`${baseUrl}/v1/paycheck/pdf`, data, {responseType: 'blob'});
const fr = new FileReader();
fr.onload = async () => {
const fileUri = `${FileSystem.documentDirectory}/document.pdf`;
const result = await FileSystem.writeAsStringAsync(fileUri, fr.result.split(',')[1], {encoding: FileSystem.EncodingType.Base64});
saveFile(fileUri);
};
fr.readAsDataURL(response.data);
In our project we are using the MERN stack
I want to create a generic function whose input is the path to any api endpoint in our server and the JSON package to POST to the server. I want it to return the JSON sent back from the server.
That way when we are developing our mobile app and web app, we can simply use this function for all of our api endpoint POSTs.
I'm very new to using React/React-Native so I'm sure that I'm not understanding some sort of key concept.
Here is what I have so far:
import React from 'react';
// returns whatever the respective apiEndpoint is suppose to return
function postToAPI(route, package2send)
{
async() =>
{
try
{
const payload = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: package2send
}
const res = await fetch(route, payload);
console.log(res);
const data = await response.json();
console.log(data);
return data;
}
catch(error)
{
console.error(error);
}
}
}
export default postToAPI;
Whenever I call this function from my Login.js after I
import { postToAPI } from './postToAPI'
I get this error: 'TypeError: Object(...) is not a function'
I'm sure there are multiple things wrong with this code, so if someone could steer me in the right direction, it would be greatly appreciated.
If you export the function as default, you must import without bracket like that.
import postToAPI from './postToAPI';
If you would like to write a generic API call class, I advise you this class which I wrote before.
import { BASE_URL } from "../config";
import { Actions } from "react-native-router-flux";
import { deleteUserInfo } from "./SessionHelper";
const API_URL = BASE_URL;
class ApiHelper {
private accessToken?: string;
constructor() {
this.accessToken = undefined;
}
setAccessToken = (accessToken: string) => {
this.accessToken = accessToken;
};
getAccessToken = () => {
return this.accessToken;
};
getRequest = async (endpoint: string) => {
try {
const response = await fetch(`${API_URL}${endpoint}`, {
method: "GET",
headers: {
"x-access-token": `${this.accessToken}`
}
});
const responseJson = await response.json();
return responseJson;
} catch (error) {
console.error(error);
}
};
postRequest = async (endpoint: string, body: any) => {
try {
const response = await fetch(`${API_URL}${endpoint}`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"x-access-token": `${this.accessToken}`
},
body: JSON.stringify(body)
});
const responseJson = await response.json();
const finalResponse = { data: responseJson, status: response.status };
if (response.status === 401) {
deleteUserInfo();
this.accessToken = undefined;
Actions.auth();
}
return finalResponse;
} catch (error) {
console.error(error);
return error;
}
};
patchRequest = async (endpoint: string, body: any) => {
try {
const response = await fetch(`${API_URL}/${endpoint}`, {
method: "PATCH",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"x-access-token": `${this.accessToken}`
},
body: JSON.stringify(body)
});
const responseJson = await response.json();
const finalResponse = { data: responseJson, status: response.status };
if (response.status === 401) {
deleteUserInfo();
this.accessToken = undefined;
Actions.auth();
}
return finalResponse;
} catch (error) {
console.error(error);
}
};
deleteRequest = async (endpoint: string, body: any) => {
try {
const response = await fetch(`${API_URL}/${endpoint}`, {
method: "DELETE",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"x-access-token": `${this.accessToken}`
},
body: JSON.stringify(body)
});
const responseJson = await response.json();
const finalResponse = { data: responseJson, status: response.status };
if (response.status === 401) {
deleteUserInfo();
this.accessToken = undefined;
Actions.auth();
}
return finalResponse;
} catch (error) {
console.error(error);
}
};
}
export const APIHelper = new ApiHelper();
I have a function api inside the method onSubmit, which make request to the server:
onSubmit: async (formValues) => {
setSubmitting(true);
try {
const res = await api('api/auth/register', {
method:'POST',
body: JSON.stringify(formValues)
});
if(Array.isArray(res)){
setErrorMessage(res[0].message);
} else {
const token = res.token.token;
localStorage.setItem('myToken', token);
history.push("/home");
}
} catch(e) {
console.error(e);
} finally {
setSubmitting(false);
}
},
});
Function api is in a separate file and looks like this:
export const api = async (url, args) => {
const response = await fetch(`${apiUrl}${url}`, {
...args,
headers: {
"Content-type": "application/json; charset=UTF-8 ",
"Accept": 'application/json',
...args.headers,
},
});
return response.json();
}
This function was created simply for convenience. But now I dont need this function. I need that code from api was inside method onSubmit. That is, that the function api not exist at all.
And I did it:
onSubmit: async (formValues) => {
setSubmitting(true);
try {
const resf = await fetch(`${apiUrl}api/auth/register`, {
method:'POST',
body: JSON.stringify(formValues),
headers: {
"Content-type": "application/json; charset=UTF-8 ",
"Accept": 'application/json',
}
});
const res = resf.json();
if (Array.isArray(res)){
setErrorMessage(res[0].message);
} else {
const token = res.token.token;
localStorage.setItem('myToken', token);
history.push("/home");
}
} catch(e) {
console.error(e);
} finally {
setSubmitting(false);
}
},
});
But I have error:
TypeError: Cannot read property 'token' of undefined
Why is this error occurring?
Try with await for resf.json() because calling .json() gets you another promise for the body of the http response that is yet to be loaded.
const res = await resf.json();