I am trying to convert the fetch API to axios with get method.
Prior to do this, I plan to keep using 'async, await'.
And when I replaced the code below:
// before
const fetchPlanets = async () => {
const res = await fetch("http://swapi.dev/api/planets/");
return res.json();
};
// after
const fetchPlanets = async () => {
const res = await axios
.get("http://swapi.dev/api/planets/")
.then((respond) => {
respond.data;
});
};
async can be used when to address the function.
and returned const res as res.json();
Also...axios does not require to res.json as it returned as json type.
That's how I understand this so far. And with fetch API, this work flawlessly.
How the code should be to let axios work as I expected?
// Planets.js
import React from "react";
import { useQuery } from "react-query";
import Planet from "./Planet";
// import axios from "axios";
const fetchPlanets = async () => {
const res = await fetch("http://swapi.dev/api/planets/");
return res.json();
};
const Planets = () => {
const { data, status } = useQuery("planets", fetchPlanets);
console.log(data);
return (
<div>
<h2>Planets</h2>
{status === "loading" && <div>Loading data...</div>}
{status === "error" && <div>Error fetching data!</div>}
{status === "success" && (
<div>
{data.results.map((planet) => (
<Planet key={planet.name} planet={planet} />
))}
</div>
)}
</div>
);
};
export default Planets;
And Planet.js; just in case.
import React from "react";
const Planet = ({ planet }) => {
return (
<div className="card">
<h3>{planet.name}</h3>
<p>Population - {planet.population}</p>
<p>Terrain - {planet.terrain}</p>
</div>
);
};
export default Planet;
There are 2 problems in your axios code.
You should return respond.data.
You should return the whole axios response.
So this would work:
const fetchPlanets = async () => {
return await axios
.get("http://swapi.dev/api/planets/")
.then((respond) => {
return respond.data;
});
};
Related
I don't really understand why, if I use asyn await directly to call api and I get data immediately when the component mount inside useEffect(), but when I call getLevels() from my selectApi.js, it return undefined when the component mount. See code below:
App.js
import axios from "axios";
import React, { useEffect, useState } from "react";
import { getLevels } from "./selectApi";
export default function App() {
const [options, setOptions] = useState([]);
useEffect(() => {
loadLevels();
}, []);
const loadLevels = async () => {
//Working fine if I use call await API directly in this file
const res = await axios.get("http://localhost:3040/v2/feedback/levels");
console.log("Data ----> ", res); //working fine
setOptions(res.data)
/* Not working if I import getLevels() from selectApi.js
getLevels().then((res) => {
console.log("Data --> ", res); //return Data --> Undefined when component load
});*/
};
return (
<div className="App">
<h1>Hello Select</h1>
<select>
<option value="">Please select</option>
{options.length > 0 &&
options.map((item) => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
</div>
);
}
SelectApi.js
const ENDPOINT_URL = "http://localhost:3040/v2/feedback/";
export const getLevels = async () => {
await axios.get("http://localhost:3040/v2/feedback/levels");
};
Working fine when I call api directly in App.js
Try this in selectApi.js
export const getLevels = async () => {
return await axios.get("http://localhost:3040/v2/feedback/levels");
};
On this case I am trying to show the "_id".
I made the code based on this video.
But by just looking at his API I can see that his data is little different, how can I adapt it to work with my API
import "./App.css";
import axios from "axios";
import { useEffect, useState } from "react";
const App = () => {
const [leitura, setLeitura] = useState([]);
const getLeituraData = async () => {
try {
const data = await axios.get(
"https://estufaarduino.herokuapp.com/sistema/leituras"
);
console.log(data.data);
setLeitura(data.data);
} catch (e) {
console.log(e);
}
};
useEffect(() => {
getLeituraData();
}, []);
return (
<div className="App">
{leitura.map((item) => {
return <p>{item._id}</p>;
})}
</div>
);
};
export default App;
I'm trying to send a delete request to API using fetch and useEffect hook in react. I want to execute the delete request with the click of a button and pass the id of the specific JSON data that has to be deleted. I'm unable to figure out how how to pass this id to fetch function under the useEffect hook.
const Display = () => {
const [state, setState] = useState([])
let deleteJSON;
const handleDelete = (_id) => {
deleteJSON = async (id) => {
const res = await fetch(`http://localhost:8080/users/${id}`, {method: 'DELETE', mode: 'cors'})
console.log(res.status)
}
}
useEffect(() => {
(async () => {
const res = await fetch('http://localhost:8080/users', {method: 'GET', mode: 'cors'})
const jsonArr = await res.json()
setState((prevState) => {
return [...prevState, ...jsonArr]
})
})();
}, [])
return (
<div className='display'>
{
state.map((json) => {
const {name, email, phone, _id} = json
return (
<div key = {_id} >
<div>
<button onClick={(event) => { handleDelete(_id)} } className="box" >Delete</button>
<button className="box">Update</button>
</div>
<h2>{_id}</h2>
<h2>{name}</h2>
<h2>{email}</h2>
<h2>{phone}</h2>
</div>
)
})
}
</div>
)
}
As you can see I've passed the id to the handleDelete function but I can only call the deleteJSON function inside the useEffect hook. But inside the useEffect hook, I can't get access to this function.
i have the following issue with getStaticPaths of Next.JS:
TypeError: cias.map is not a function
https://i.stack.imgur.com/IVZDp.png
Can someone help me with this, please?
Code:
import React from 'react'
import { Container } from '../../../styles/pages/container'
import { GetStaticProps, GetStaticPaths } from 'next'
import fetch from 'isomorphic-unfetch'
export const getStaticPaths: GetStaticPaths = async () => {
const res = await fetch('http://localhost:3000/api/infocadcias')
const cias = await res.json()
const paths = cias.map(cia => ({
params: { id: cia.ID.toString() }
}))
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const res = await fetch(`http://localhost:3000/infocadcias/${params.id}`)
const cia = await res.json()
return cia
}
// eslint-disable-next-line #typescript-eslint/explicit-module-boundary-types
export default function InfoCia({ cia }) {
return (
<Container>
<ul>
{cia.map(p => (
<li className="cia" key={p.ID}>
<span>Name: {p.Name}</span>
</li>
))}
</ul>
</Container>
)
}
Edit: I answered the wrong question below, but you should still take a look at that. you are getting that error because cias is not an array. Try logging that variable and update your question with the result if you still don't have a solution. It may be something like {cias: [...]} in which case you would need to change the map to cias.cias.map(...) OR destructure the variable on assignment const { cias } = await res.json()
In your getStaticProps function you are not returning in the proper format. You need to return an object with the props key like this:
{
props: {
cia: cia
}
}
You can refer to the NextJS docs on getStaticProps here: https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
If that doesn't fix it, you should make sure that your await res.json() is returning an array.
Full example with update:
import React from 'react'
import { Container } from '../../../styles/pages/container'
import { GetStaticProps, GetStaticPaths } from 'next'
import fetch from 'isomorphic-unfetch'
export const getStaticPaths: GetStaticPaths = async () => {
const res = await fetch('http://localhost:3000/api/infocadcias')
const { cias } = await res.json()
const paths = cias.map(cia => ({
params: { id: cia.ID.toString() }
}))
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const res = await fetch(`http://localhost:3000/infocadcias/${params.id}`)
const { cia } = await res.json()
return {
props: {
cia: cia
}
}
}
// eslint-disable-next-line #typescript-eslint/explicit-module-boundary-types
export default function InfoCia({ cia }) {
return (
<Container>
<ul>
{cia.map(p => (
<li className="cia" key={p.ID}>
<span>Name: {p.Name}</span>
</li>
))}
</ul>
</Container>
)
}
```
My return function doesn't work inside function, pls help me to solve this problem.
import React from 'react';
import axios from 'axios';
const Category = () => {
//const[data, useData]=useState([]);
const FuncMen =() =>{
var e = document.getElementById("menid");
var country = e.options[e.selectedIndex].value;
if(country === "T-shirt"){
axios.post('http://localhost:8011/api/social/finddatamen',{country})
.then((res) => {
var men = res.data.res.filter(filtereddata => filtereddata.category === "tshirt" )
console.log('selected value is',men);
men &&men.map((val,i)=>{
console.log("Tshirtt:",val.Tshirt,"Price:",val.price);
return(
<div key={i}>
<h1>hello</h1>
{val.Tshirt},
{val.price}
</div>
)
})
})
.catch((error) => {
console.log('error block called',error);
})
}
You need to return the JSX (div, h1) outside of the .then block, after the .catch.
I don't know why you have FuncMen nested inside Category. I would remove FuncMen and just use something like this if you want to use hooks..
import React, {useState} from 'react';
import axios from 'axios';
const Category =() =>{
const [category, setCategory] = useState(undefined)
var e = document.getElementById("menid");
var country = e.options[e.selectedIndex].value;
if(country === "T-shirt"){
axios.post('http://localhost:8011/api/social/finddatamen'{country})
.then((res) => {
var men = res.data.res.filter(filtereddatafiltereddata.category=== "tshirt" )
console.log('selected value is',men);
setCategory(men)
.catch((error) => {
console.log('error block called',error);
})
}
}
return (
<div>
<h1>hello {category}</h1>
</div>
)
)
}
Then in some other component, use it:
render() {
return (<Category />)