React Axios - Pass Hook as Parameter for Axios Params - reactjs

I am new to React & Axios, I'm trying to work my head around how to change the GET instance properties based on user inputs... If I am going about it the wrong way please direct me.
I want the selected dataFormat to pass to the params of the Axios.getData()
At the moment I can only get it to pass the object rather than its value.
Thanks in advance
Here is the code to fetch the data:
function App() {
let [responseData, setResponseData] = React.useState([]);
const [dataFormat, setDataFormat] = React.useState("json");
const fetchData = (e) => {
e.preventDefault();
console.log({dataFormat});
api
.getData(dataFormat)
.then((response) => {
console.log("Hello");
console.log(response);
setResponseData(response.data);
})
.catch((error) => {
console.log(error);
});
};
Here is the Axios instance
enter image description here
Here is the error I am receiving:
enter image description here

First you need to install the express library. Then, import cors and also use express.json() for parsing the json as shown below:
const express = require("express");
const app = express();
const cors = require("cors");
app.use(express.json());
app.use(cors());
function App() {
let [responseData, setResponseData] = React.useState([]);
const [dataFormat, setDataFormat] = React.useState("json");
const fetchData = (e) => {
e.preventDefault();
console.log({dataFormat});
api
.getData(dataFormat)
.then((response) => {
console.log("Hello");
console.log(response);
setResponseData(response.data);
})
.catch((error) => {
console.log(error);
});
};

Related

React Query useQuery & Axios

I'm trying to create an API function with a help of React Query and Axios.
When I'm using useQuery with vanilla fetch function - it all works perfectly.
export const useGetDebts = async () => {
const { families } = appStore.user;
const res = useQuery("getDebts", async () => {
const res = await fetch(`${API_URL}/api/family/${families[0]}/debts`, {
method: "GET",
headers: {
Authorization: `Bearer ${appStore.token ?? ""}`,
},
});
const parsedBody: DebtsResponse = await res.json();
return parsedBody;
});
return res;
};
But when I switch the vanilla fetch function to Axios - I get an error status of 500 (not sure if it comes from React Query or Axios).
export const useGetDebts = async () => {
const { families } = appStore.user;
const res = useQuery("getDebts", async () => {
const res = await axiosInstance.get<DebtsResponse>(`/api/family/${families[0]}/debts`);
return res.data;
});
return res;
};
Thanks in advance for any explanations/suggestions.
P.s. The axiosInstance works fine with the useMutation hook. So it only makes me more confused. =(
export const useGetDebt = () => (
useMutation(async (id: number) => {
const { families } = appStore.user;
const res = await axiosInstance.get<DebtResponse>(`/api/family/${families[0]}/debts/${id}`);
return res.data;
})
);
P.s.s. I'm working with React Native if it's somehow relevant.
react-query doesn't give you any 500 errors because react-query doesn't do any data fetching. It just takes the promise returned from the queryFn and manages the async state for you.
I'm not sure if the fetch code really works because it doesn't handle any errors. fetch does not transform erroneous status codes like 4xx or 5xx to a failed promise like axios does. You need to check response.ok for that:
useQuery(['todos', todoId], async () => {
const response = await fetch('/todos/' + todoId)
if (!response.ok) {
throw new Error('Network response was not ok')
}
return response.json()
})
see Usage with fetch and other clients that do not throw by default.
So my best guess is that the fetch example also gives you a 500 error code, but you are not forwarding that error to react-query.

react-native not rendering the response of axios response

I have written an axios request in react-native useEffect.The request is succesfull in backend and returning a the right response in terminal.But the useEffect hook is not working according to it .It is still returning product as undefined and not changing the state.
If it all works well the product would contain the product variable.
It only works when I save it again and then it shows the product . Am I missing something here ?
Thanks in Advance !!
const [product, setProduct] = useState();
useEffect( () => {
getproductinfo()
if (props.editMode) {
AsyncStorage.getItem("jwt")
.then((res) => {
setToken(res);
})
.catch((error) => console.log(error));
}
console.log(product, "this is product");
},
[],
)
this is my function
const getproductinfo = async () => {
await axios
.get(`${baseURL}products/get/product/${props.product}`)
.then((res)=> {setProduct(res.data)
})
.catch((error)=> {
console.log(error);
console.log("this is order card product card error ")
});
}
getproductinfo is an async function and you don't use await in the useEffect hook so the code continues to run while the axios request is not yet resolved. However you can't use an async function as useEffect so I suggest the following approach
useEffect( () => {
const asyncFunction = async() {
await getproductinfo();
console.log(product, "this is product");
}
asyncFunction();
// Rest of your code....
},
[],
)

how do I perform conditial query params in axios?

I am trying to build a conditional dynamic react component where makes an API call based on the user interaction, but if the user types something in the search bar. I want to add search= param the otherwise use /list endpoint without query params. I am using currently Axios , and I would like to know some approach to do the following
const FeedsList = () => {
const [feed, setFeed] = useState([]);
const [currentPageUrl, setCurrentPageUrl] = useState("http://localhost:8001/api/v1/feeds/list/")
const performSearch = () => {
//setLoading(true)
api.get(currentPageUrl).then(res => { // axios call
setLoading(false)
setFeed(res.data.results)
}).catch(function(error){
console.log(error);
});
}
const handleSearch = (e) =>{
console.log(e.target.value)
//performSearch();
}
useEffect(() => {
performSearch()
}, [currentPageUrl]);
if (loading) return "Loading..."
}
export const api = axios.create(
{baseURL : 'http://localhost:8001/api/v1/feeds/list/'}
)
user input
<input type="text" placeholder="Enter keyword" onChange={event => handleSearch(event)}/>
Store user input to state, not URL, and then construct your URL from initial value (list) and user input, if any:
const FeedsList = () => {
const [loading, setLoading] = useState(false);
const [feed, setFeed] = useState([]);
const [searchString, setSearchString] = useState("");
const performSearch = (searchString) => {
setLoading(true);
let url = "http://localhost:8001/api/v1/feeds/list/";
// you might want to escape this value, and sanitize input on the server
if (searchString) url = `${url}?search=${searchString}`;
const cancelTokenSource = axios.CancelToken.source();
return api
.get(url, { cancelToken: cancelTokenSource.token })
.then((res) => {
setLoading(false);
setFeed(res.data.results);
})
.catch(function (error) {
console.log(error);
});
return cancelTokenSource;
};
const handleSearch = (event) => {
setSearchString(event.target.value);
};
useEffect(() => {
let token = performSearch(searchString);
return () => token.cancel();
}, [searchString]);
if (loading) return "Loading...";
};
You might want to debounce or throttle requests, so you will not bombard your server with requests on each keystroke
The Axios api allows for passing a second parameter to the get method which is the config for the request being sent. That config object takes a params property that would be parsed and appended onto the url as a query string. The nice thing is if the params object is empty it will be like not passing anything at all. A fuller example here on their GitHub page.
Passing an empty params object is the same as passing no params object at all in terms of what is requested.
// both lines request url looks like this => https://jsonplaceholder.typicode.com/users
axios.get('https://jsonplaceholder.typicode.com/users')
axios.get('https://jsonplaceholder.typicode.com/users', { params: {} })
To answer your question you could conditionally just create the params based on whether there is a value from the search input, something like the following:
const performSearch = () => {
const config = search === '' ? {
params: {}
} : {
params: { search } // same as { search: search }
}
api.get(currentPageUrl, config).then(res => {
// do something with response
}).catch(function(error){
console.log(error);
});
}
An assumption in the above would be that you stored the search value in state somewhere and add it to your useEffect dependencies list, referencing it in performSearch.

2 API Calls with Axios, both show up in local server - but only one appears deployed

I made 2 API calls in React with Axios. In my local server both calls appear, after being deployed to Netify, only the first API call appears. I don't know what is causing it bc I have no error messages.
Right image is after it's been deployed, and the left image is the one on the local server. I XXXed my key, so it doesn't appear in the code
import axios from 'axios';
const API_URL = 'https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=XXXX';
const API_URL2= 'http://newsapi.org/v2/top-headlines?sources=ars-technica&apiKey=XXXX';
export const getNews = async () => {
const result = await axios.get(API_URL)
.then(response => {
return response.data.articles;
});
return(result);
}
export const getNews2 = async () => {
const result = await axios.get(API_URL2)
.then(response => {
console.log(response.data)
return response.data.articles;
})
.catch(function (error) {
// handle error
console.log(error);
})
.finally(function () {
// always executed
});
return(result);
Why first is https and second http ?

How to pass value to Koa2

I have an react app that I want to pass value down to a koa server.
let data = new FormData()
data.append('json', JSON.stringify(token))
fetch('/charge', { method: 'POST', body: data })
.then((res) => {
return res.json()
})
.then((json) => {
console.log('something wrong')
console.log(json)
})
and below is my server code
const config = require('../config')
const server = require('../server/main')
const router = require('koa-router')()
const parse = require("co-body")
const port = config.server_port
server.use(router.routes())
router
.post('/charge', function (ctx, next) {
console.log(ctx.request.body)
console.log('howyd')
ctx.body = "howdy"
})
Just can't get the value passing down from client. Do you guys know what is going on?
Make sure you're using the body parser. It looks like you're requiring it in, but not actually using it. Something like this (untested):
const config = require('../config')
const server = require('../server/main')
const router = require('koa-router')()
const parse = require("co-body")
const port = config.server_port
server.use(router.routes())
router
.post('/charge', async (ctx, next) => {
let body = await parser.json(ctx.request)
console.log(body)
console.log('howyd')
ctx.body = "howdy"
})

Resources