React: How to get data from Axios, not Promise? - reactjs

I'm trying to get data from a link but all I get is a Promise.
Here is my example code:
import axios from "axios";
export default function App() {
const url = `https://finnhub.io/api/v1/stock/profile2?symbol=GME&token=c6a500qad3idi8g5o2v0`;
const fetchData = async (u) => {
return await axios.get(u).then((res) => res.data);
};
return (
<div className="App">
<button onClick={() => console.log(fetchData(url))}>click me</button>
</div>
);
}
I don't know which part of the code is wrong that it keeps giving out the Promise like the photo here:
Please help. I appreciate it!

You can do it like this
import axios from "axios";
export default function App() {
const url = `https://finnhub.io/api/v1/stock/profile2?symbol=GME&token=c6a500qad3idi8g5o2v0`;
const [data, setData] = React.useState(null);
const fetchData = async (u) => {
return await axios.get(u).then((res) => {
setData(res.data);
console.log(res.data.name);
});
};
return (
<div className="App">
<button onClick={() => fetchData(url)}>click me</button>
Name :{data?.name}
</div>
);
}

Related

Expected `onClick` listener to be a function. Want to load data onlick

i was preparing for an interview and working with questions given on google, i have created everything perfectly well,but what i want for data to be loaded after clicking the button, but i think i am making an error, how am i supposed to do that? can anyone guide me.
import "./styles.css";
import {useEffect, useState} from 'react'
import axios from 'axios'
export default function App() {
const[count, setCount] = useState(0)
const[randomUserDataJSON, setRandomUserDataJSON] = useState('')
useEffect(() => {
fetchRandomData().then(randomData=> {
setRandomUserDataJSON(randomData ||'' )
})
}, [])
const fetchRandomData = () => {
return axios.get('https://randomuser.me/api')
.then(({data}) => {
console.log(data);
return JSON.stringify(data)
})
.catch(error => {
console.log(error)
})
}
return (
<div className="App">
<h2>how to implemenet useEffect</h2>
<button onClick="randomUserDataJSON">Fetch Random Data</button>
<pre> </pre>
</div>
);
}
note also tried:
<button onClick={randomUserDataJSON}>Fetch Random Data</button>
import "./styles.css";
import {useState} from 'react'
import axios from 'axios'
export default function App() {
const[count, setCount] = useState(0)
const[randomUserDataJSON, setRandomUserDataJSON] = useState('')
const fetchRandomData = () => {
axios.get('https://randomuser.me/api')
.then(({data}) => {
console.log(data);
setRandomUserDataJSON(JSON.stringify(data)||'' )
})
.catch(error => {
console.log(error)
})
}
return (
<div className="App">
<h2>how to implemenet useEffect</h2>
<button onClick={fetchRandomData}>Fetch Random Data</button>
<pre> </pre>
</div>
);
}
You don't need useEffect since the action is performed on a click event
The onClick event needs to be wrapped in curly braces {}
export default function App() {
const[count, setCount] = useState(0)
const[randomUserDataJSON, setRandomUserDataJSON] = useState('')
const fetchRandomData = () => {
return axios.get('https://randomuser.me/api')
.then(({data}) => {
console.log(data);
return JSON.stringify(data)
})
.catch(error => {
console.log(error)
})
}
return (
<div className="App">
<h2>how to implemenet useEffect</h2>
<button onClick={fetchRandomData}>Fetch Random Data</button>
<pre>{randomUserDataJSON}</pre>
</div>
);
}

Fetching API data, nested in two arrays and displaying it with React

I am trying to fetch data that is nested in two unnamed arrays API Endpoint.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const API_URL = 'https://my-json-server.typicode.com/TomSearle/cb-devtest-api/products';
const MyComponent = () => {
const [posts, setPosts] = useState([]);
const fetchData = async () => {
const { data } = await axios.get(API_URL);
setPosts(data);
console.log(data);
};
useEffect(() => {
fetchData();
}, []);
return (
<div>
{posts.length > 0 ? (
<div>
{posts.map((post) => (
<div>
<h2>{post.price}</h2>
<p>{post.stock_count}</p>
</div>
))}
</div>
) : (
<p className="loading">Loading... </p>
)}
</div>
);
};
export default MyComponent;
console.log shows an Array with 10 Objects, how could I destructure that data to display it dynamically? Any help would be appreciated.
Your array is nested one more level somehow. Better to fix it in the backend or simply access the posts like below.
{
posts[0].map((post) => (
<div>
<h2>{post.price}</h2>
<p>{post.stock_count}</p>
</div>
))
}
Working Demo

How can I send a request to API with on click of my button in React hooks?

So I currently have this code that has a useEffect() that shows the data from the API every time. I refresh, but I'm trying to make that data display only when I click on my button. I'm not too sure where to go with my code.
import React, { useState, useEffect } from 'react';
import './App.css';
import axios from 'axios';
function App() {
const [image, setImage] = useState(false);
// I tried to put a onclick function, but not sure what to add here
const handleChange = ()
=> {
setImage(true)
}
// this code displays my data on refresh
useEffect(() => {
axios
.get(
'https://api.com'
)
.then(res => {
setImage ?
setImage(res.data.faces[0].urls[4][512]) : console.log('nothing')
})
.catch(err => {
console.log(err.message);
});
}, []);
return (
<div className='App'>
<h1>Photo Generator</h1>
<img src={image} />
<button onClick={handleChange}>Show new Image</button>
</div>
);
}
I've updated your code.
Try this code, let me know if it works for you. :)
import React, { useState } from "react";
import "./App.css";
import axios from "axios";
function App() {
const [image, setImage] = useState(false);
// I tried to put a onclick function, but not sure what to add here
const handleChange = () => {
axios
.get("https://api.com")
.then(res => {
const uri = res.data.faces[0].urls[4][512];
if (uri) {
setImage(uri);
} else {
console.log("nothing");
}
})
.catch(err => {
console.log(err.message);
});
};
return (
<div className="App">
<h1>Photo Generator</h1>
{image && <img src={image} alt="yourImage" />}
<button type="button" onClick={handleChange}>
Show new Image
</button>
</div>
);
}
You don't need to use useEffect Hook in this case.
also don't need to check setImage inside of API callback function.
You could do it like this
import React, {useState, useEffect} from 'react';
import './App.css';
import axios from 'axios';
function App() {
const [image, setImage] = useState('');
const [displayImage, setDisplayImage] = useState('none');
const handleChange = () => {
setDisplayImage('flex');
};
useEffect(() => {
axios
.get('https://api.com')
.then((res) => {
setImage
? setImage(res.data.faces[0].urls[4][512])
: console.log('nothing');
})
.catch((err) => {
console.log(err.message);
});
}, []);
return (
<div className="App">
<h1>Photo Generator</h1>
<div style={{display: displayImage}}>
<img style src={image} />
</div>
<button onClick={() => handleChange()}>Show new Image</button>
</div>
);
}
You could also do
<button onClick={() => setDisplayImage('flex')}>Show new Image</button>

TypeError: props... is not a function in reactjs

I'm trying to get data API from star wars website with react project and here's my code:
const Form = (props) => {
const [search, setSearch] = useState("people");
const [searchID, setSearchID] = useState(1);
const [responseData, setResponseData] = useState({});
useEffect(() => {
buttonAPI();
setSearch(props.type);
}, [props.type]);
const buttonAPI = () => {
axios
.get(`https://swapi.dev/api/${props.type}/`)
.then((res) => {
setResponseData(res.data);
})
.catch((err) => {
console.log(err);
});
};
const onSubmit = (e) => {
e.preventDefault();
navigate(`/${search}/${searchID}`);
};
return (
<div className="container" style={pageStyle}>
<form onSubmit={onSubmit}>
.
.
.
)
I'm getting this error while trying to add props.setSearch(props.type); into useEffect
Here is my github for this project:
https://github.com/nathannewyen/reactjs-practice/tree/master/luke-api
From your App.jsx:
import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Info from "./components/Info";
import Form from "./components/Form";
function App() {
return (
<div className="App">
<Form />
<Info />
</div>
);
}
export default App;
You pass nothing to Form component, so the props is empty and you cannot call a function that not exists.

React useEffect for Loading Data

I'm learning React Hooks and I'm wondering what would be the most effective way to reload data while being "hook friendly".
I've identified 3 use cases (the latest apparently being the "more appropriate"
With Copied Code
//Example of Using useEffect Hooks by duplicating code
import React, {useState, useEffect} from 'react'
import axios from 'axios'
export default () => {
const [deals, setDeals] = useState([])
const [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
})
}, [setDeals])
return(
<div className="Deals">
{loading &&
<p>It's loading</p>
}
{!loading &&
<>
{deals.map((deal, i) => (
<div key={i} className="Deal Note">
{deal.label}
</div>
))}
</>
}
<button onClick={() => {
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
}).catch(res => {
setDeals([{label: 1, label: 2}])
setLoading(false)
})
}}>Fetch Again</button>
</div>
)
}
By Passing Hooks inside an external function. Code reuse - using hooks inside another function
I'm understanding this is not "the way" to use hooks although this was my first go-to solution
//Example of Using useEffect Hooks by feeding hooks to external function
import React, {useState, useEffect} from 'react'
import axios from 'axios'
const usefetchMore = (setDeals, setLoading) => {
console.log("usefetchMore")
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
})
}
export default () => {
const [deals, setDeals] = useState([])
const [loading, setLoading] = useState(false)
useEffect(() => {
usefetchMore(setDeals, setLoading)
}, [setDeals])
return(
<div className="Deals">
{loading &&
<p>It's loading</p>
}
{!loading &&
<>
{deals.map((deal, i) => (
<div key={i} className="Deal Note">
{deal.label}
</div>
))}
</>
}
<button onClick={() => usefetchMore(setDeals, setLoading)}>Fetch Again</button>
</div>
)
}
This one seem to be "the proper way of doing it" and is based on having useEffect re-triggered because it's listening to the changes on the reload variable which is there just to re-trigger it.
//Example of Using useEffect Hooks with variable to re-trigger useEffect
import React, {useState, useEffect} from 'react'
import axios from 'axios'
/* DOESN't WORK */
export default () => {
const [deals, setDeals] = useState([])
const [loading, setLoading] = useState(false)
const [reload, setReload] = useState(0)
useEffect(() => {
console.log("Deal4.useEffect")
setLoading(true)
axios({
method: 'GET',
url: `http://localhost:1338/deals`
}).then(res => {
setDeals(res.data)
setLoading(false)
})
}, [setDeals, reload])
return(
<div className="Deals">
{loading &&
<p>It's loading</p>
}
{!loading &&
<>
{deals.map((deal, i) => (
<div key={i} className="Deal Note">
{deal.label}
</div>
))}
</>
}
<button onClick={() => {
setReload(reload + 1)
}}>Fetch Again</button>
</div>
)
}
My question is: If I were to build a component that shows loading and allows to refresh itself, which way would be the proper way to write it with "React hooks"?
Create a component in /src/ called Photos.js and give it a basic list:
import React from "react";
import { useFetch } from "./hooks";
function Photos() {
const [data, loading] = useFetch(
"https://jsonplaceholder.typicode.com/photos?albumId=1"
);
return (
<>
<h1>Photos</h1>
{loading ? (
"Loading..."
) : (
<ul>
{data.map(({ id, title, url }) => (
<li key={`photo-${id}`}>
<img alt={title} src={url} />
</li>
))}
</ul>
)}
</>
);
}
export default Photos;
Now we need a Hook! Create a file in the same directory called hooks.js and fill it with this:
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
async function fetchUrl() {
const response = await fetch(url);
const json = await response.json();
setData(json);
setLoading(false);
}
useEffect(() => {
fetchUrl();
}, []);
return [data, loading];
}
export { useFetch };
Import the Photos component into App.js and yarn start. Done!

Resources