I am trying to return the response from an axios API call. I don't quite get what a promise is and all the tutorials/information I find they only log the response, I want to return it.
Here is what I have, but when I call getPokemon it's undefined.
const axios = require('axios');
const getPokemon = () => {
axios.get('https://pokeapi.co/api/v2/pokemon/')
.then(function (response) {
console.log("Response:", response.data.results);
return response.data.results;
})
.catch(function (error) {
return null;
});
}
export {getPokemon};
If this is a React app then you want to do your Axios call in componentDidMount. Axios automatically returns a promise.
class Example extends Component {
constructor(props) {
super(props);
this.state = {
data: ""
};
}
componentDidMount() {
axios
.get("https://pokeapi.co/api/v2/pokemon/")
.then(res => {
console.log(res);
this.setState({
data: res.data.results
});
})
.catch(err => {
console.log(err);
});
}
render() {
let pokemon = this.state.data;
let display = Object.values(pokemon).map((item, key) => {
return (
<div>
<p>{item.name}</p>
<p>{item.url}</p>
</div>
);
});
return (
<div>{display}</div>
);
}
}
export default Example;
Doing it like this will send the Axios request after the React app has loaded and set the JSON data in the component state. You should be able to access the JSON data via this.state.data.
Check out this Codepen example with working API call.
Well, first of all, I suggest you read about promises.
a good method for achieving what you need is by using async/await syntax check out the following code:
const axios = require('axios');
const getPokemon = async () => {
try{
let res = await axios.get('https://pokeapi.co/api/v2/pokemon/');
return res.data.results;
}
catch(error){
return null //that's what you did in your code.
}
}
export {getPokemon};
Remove ".result"
const axios = require("axios");
const getPokemon = async () => {
try {
let res = await axios.get("https://jsonplaceholder.typicode.com/users");
return res.data; **here remove his .result**
} catch (error) {
return null; //that's what you did in your code.
}
};
export default getPokemon;
In index.js or any page call it:
import getPokemon from "./GetPokimon";
const xyz = async () => {
const data = await getPokemon();
alert(JSON.stringify(data));//u will see the data here
}
xyz(); //calling getPokemon()
Related
I'm currently working on a React project. Using the Axios library, I need to get data from the API and write it to a variable.
Searching the web for this, I found the only option is via Promise.then(), but that's not what I want, as the result is simply returned to the next Promise.then().
I need Axios to return the result and after that my function returns this result instead of with the tag so to speak. Sample code below. Thanks in advance.
function getData() {
let packsId = '11111';
if (packsId) {
return axios.get('http://localhost:8000/api/words?id=' + packsId)
.then((response) => {
return response.data.title;
})
.catch((error) => {
return error.code;
});
}
else {
return "Doesn't exist";
}
}
export default function WordsPack() {
let result = getData(); // here returned Promise, not String
return <div>{ result }</div>
}
If you wanna call let result = getData() at the top level of your component as you showed in your example, you would wanna transform getData to a custom hook, as an example like so:
import { useState, useEffect } from "react";
// ⚠️ Notice it start with "use":
export default function useGetData() {
const [result, setResult] = useState("Loading..."); // the data to show while fetching
useEffect(() => {
let packsId = "11111";
if (packsId) {
axios
.get("http://localhost:8000/api/words?id=" + packsId)
.then((response) => setResult(response.data.title))
.catch((error) => setResult(error.code));
} else {
setResult("Doesn't exist");
}
}, []);
return result;
}
export default function WordsPack() {
let result = useGetData();
return <div>{result}</div>
}
you need to use Async/Await
async function getData() {
let packsId = '11111';
if (packsId) {
try{
return await axios.get('http://localhost:8000/api/words?id=' + packsId);
}
catch(ex){
//error handle
}
}
else {
return <div>Doesn't exist</div>;
}
}
now to read the value you have to call with await in the same way
export default async function WordsPack() {
let result = await getData(); // here returned Promise, not Object with data
return <div>{ result }</div>
}
if it's inside component where you are calling getData()
use useEffect and implement with state
export default async function WordsPack() {
const [result, setResult] = useState();
useEffect(() => {
(async() => {
const dataResult = await getData();
setResult(dataResult)
})();
})
return <div>{ result }</div>
}
for more references you can read
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
I'm trying to pre render page using getServerSideProps in Next.js and everything works perfectly.
But what if the axios call failed due to server issue or Network error?
How can I repeat the call?
Here's my code:
export async function getServerSideProps() {
let ImagesList = {};
await axios
.get("https://www.*****.com/api/home")
.then((response) => {
if (response.data) {
ImagesList = response.data
}
})
.catch((err) => { });
return {
props: {
ImagesList,
}
}
}
you can try to wrap your axios call inside a while loop,
let result = false;
while(!result) {
await axios
.get("https://www.*****.com/api/home")
.then((response) => {
result = true
if (response.data) {
ImagesList = response.data
}
})
.catch((err) => { });
}
i have a next project.in this project i used axios for send and recieved request data.
but i have a problem when i use axios in getStaticProps function i get an error in my index.js page
this is my index.js
import axios from "axios";
const Home = (props) => {
console.log(props);
return <div>d</div>;
};
export async function getStaticProps() {
const res = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
return {
props: {
data: res
}
};
}
export default Home;
and this is my index.js page in my browser
I would be very grateful if anyone could help me
it worked
try {
const result = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
const data = result.data;
return {
props: {
data: data
}
}
} catch (error) {
console.log(error);
}
You should use res.data. Next time, I recommend to use console.log(res) and see the object that you receive
Add JSON.stringify when calling an asynchronous function that returns an object.
Try modifying the getStaticProps function like this:
export async function getStaticProps() {
const res = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
const stringRes = JSON.stringify(res);
return {
props: {
data: stringRes
}
};
}
OR
Use .text() to convert the response data to text like this:
export async function getStaticProps() {
const res = await axios.get('https://jsonplaceholder.typicode.com/todos/1').lean();
const textRes = await res.text();
return {
props: {
data: textRes
}
};
}
I'm new in react and what i'm trying to do is a proxy pattern with axios ouside my component "home" but when i put axios in my separated class it doesn't work. But it works inside my component
Here's my proxy class:
import axios from "axios";
export default class daniProxy {
constructor(proxyUrl, apiUrl) {
this.proxyUrl = proxyUrl;
this.apiUrl = apiUrl;
}
getDanis(restUrt) {
let ds = {};
axios
.get(this.proxyUrl + this.apiUrl + restUrt)
.then((danis) => {
ds = {
data: danis.data,
};
})
.catch((err) => {
console.log(err);
});
return ds;
}
}
And here is my home component class:
class home extends Component {
state = {
danis: null,
};
componentDidMount() {
let prox = new daniProxy(proxyurl,apiurl);
console.log(prox.getDanis('/getDanis'))
}
any idea why it doesn't return something?
your return ds statement wont wait axios promise to be resolved. once you call axios, next line is evaluated right away and ds is still an empty object. instead, try returning the promise:
getDanis(restUrt) {
return axios
.get(this.proxyUrl + this.apiUrl + restUrt)
.then((danis) => {
return {
data: danis.data,
};
})
.catch((err) => {
console.log(err);
});
}
now at your componentDidMount you may declare as async and do:
async componentDidMount() {
let prox = new daniProxy(proxyurl,apiurl);
const result = await prox.getDanis('/getDanis');
console.log(result);
}
or chain your promise:
componentDidMount() {
let prox = new daniProxy(proxyurl,apiurl);
prox.getDanis('/getDanis')
.then(console.log);
}
It's because the GET request is asychronous so the return execute before. You should catch the promise.
getDanis(restUrt) {
return axios
.get(this.proxyUrl + this.apiUrl + restUrt)
.then((danis) => {
return {
data: danis.data,
};
})
.catch((err) => {
console.log(err);
});
}
Then, in your component you can get the result
componentDidMount() {
let prox = new daniProxy(proxyurl,apiurl);
prox.getDanis('/getDanis').then((res) => {
console.log(res);
});
}
How to preventing unnecessary requests when update the input?
I tried below solution.But in the App file, that search is declared but never used. I tried something like: https://alligator.io/react/live-search-with-axios/.
What is the variable let token in the fileutils.js. Should I assign let token = localStorage.getItem ('token') to this variable;?
App
import search from /.utils
class App extends Component {
constructor (props) {
super(props);
this.state = {
todos: [],
}
}
search = (query) => {
axios({
url: `/api/v1/todos/{query}`,
method: "GET"
})
.then(res => {
this.setState({
todos: res.data
});
})
.catch(error => {
console.log(error);
})
render () {
return (
<input onChange={this.search} />
)
}
}
utils.js
import axios from 'axios';
const makeRequestCreator = () => {
let token;
return (query) => {
// Check if we made a request
if(token){
// Cancel the previous request before making a new request
token.cancel()
}
// Create a new CancelToken
token = axios.CancelToken.source()
try{
const res = axios(query, {cancelToken: cancel.token})
const result = data.data
return result;
} catch(error) {
if(axios.isCancel(error)) {
// Handle if request was cancelled
console.log('Request canceled', error.message);
} else {
// Handle usual errors
console.log('Something went wrong: ', error.message)
}
}
}
}
const search = makeRequestCreator()
export default search;
You can do that with a function that delays executing of your onChange.you can use debounce function from lodash.js
// _.debounce(yourSearch function, delay time);
search(e){
let str = e.target.value;
_.debounce(() => yourFunction, 500);
}