Fetch not working in React.js - reactjs

I am trying to fetch the message outputted by the following endpoint:
http://helloworld-env-2.5fwknpgms8.us-east-2.elasticbeanstalk.com/
I just ran a create-react-app to create my application and changed the code in the App.js file
New Code:
import React, { Component } from 'react';
import './App.css';
class App extends React.Component {
constructor(props){
super(props);
this.state = {
error: null,
isLoaded: false,
items: ""
};
}
componentDidMount(){
console.log("mounting component");
fetch("http://helloworld-env-2.5fwknpgms8.us-east-2.elasticbeanstalk.com/")
.then((result) => {
this.setState({
isLoaded: true,
items: result
});
});
}
render() {
console.log("rendering");
const isLoaded = this.state.isLoaded;
if(isLoaded){
return (<div> {this.state.items} </div>);
}
else{
return (
<div>loading</div>
);
}
}
}
export default App;
I keep getting the loading message.

You need to parse the response from fetch:
componentDidMount(){
fetch("http://helloworld-env-2.5fwknpgms8.us-east-2.elasticbeanstalk.com/")
.then((result) => result.json()) // here
.then((result) => {
const { a } = result; // access 'a' key from response
this.setState({
isLoaded: true,
items: a
});
});
}
Here are the docs.

Related

Unable to render data from api into table

Api url: https://dev.dashmed.in/sample-data
my code for fetching api and rendering in a table:
import React, { Component } from 'react'
import axios from 'axios'
export default class javascriptMap extends Component {
constructor(props){
super(props)
this.state = {
data: []
}
}
getData(){
axios.get('https://dev.dashmed.in/sample-data').then(res => {
var data = res.data
this.setState({data : data})
})
}
componentDidMount(){
this.getData()
}
render() {
return (
<>
<ul>
{this.state.data.map(d => (<li key={d.medName}>{d.saltName}</li>))}
</ul>
</>
)
}
}
Please point out where the error is being committed.
Because your res.data contains {status: true, data: Array(5000)}. You need to set res.data.data into state.
getData(){
axios.get('https://dev.dashmed.in/sample-data').then(res => {
const data = res.data.data
this.setState({data : data})
})
}

how to use map function with (axios/classhooks) to read from API

import React, { Component } from "react";
import axios from "axios";
class Verifry extends Component {
constructor(props) {
super(props);
this.state = {
s: "0",
user: [],
};
}
/* has title as attribute within the res.data*/
async componentDidMount() {
await axios
.get(http://10.0.0.106:8080/kuwait_elections/api/about_us)
.then((res) => {
const persons = res.data;
this.setState({ user: persons.data.title, s: "4" });
console.log(this.state.user);
});
}
componentDidUpdate() {
// this.state.user.map((u) => {
// return u;
// });
}
render() {
return (
{this.state.user.map((t) => {
return {t.title};
})}
);
}
}
export default Verifry;
Seems your return is not correct. It should be like this.
{
this.state.user.map(({title}) => {
return { title };
})
}
Note: Please format your code properly to make it easier to understand.

onClick doesn't work while trying to render: reactjs, basic API fetch

I'm trying to do a basic API fetch and show that information onClick using a button called GENERATE. All it should do for now is show the first url in the json I receive.
Once that is achieved, I want it to show the next url on each click.
App.js
import React, { Component } from 'react';
import { ThemeProvider, createToolkitTheme } from 'internaltools/theme';
import { AppHeader } from 'internaltools/app-header';
const LIGHT_THEME = createToolkitTheme('light');
const DARK_THEME = createToolkitTheme('dark');
const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
isLoading: false,
error: null,
};
}
componentDidMount(){
this.setState({ isLoading: true });
fetch(API + DEFAULT_QUERY)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong with the API...');
}
})
.then(data => this.setState({ hits: data.hits[0], isLoading: false }))
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
const { hits, isLoading, error } = this.state;
return (
<>
<button onClick={hits.url}>GENERATE</button>
</>
);
}
}
Please help me find out why my button doesn't work. And how do I iterate over the urls on each click, i.e. show the next url from the json on each click. Thanks.
You should pass a function name to your onClick handler. Then in that function you can access the data you wanted.
enter code here
import React, { Component } from 'react';
import { ThemeProvider, createToolkitTheme } from 'internaltools/theme';
import { AppHeader } from 'internaltools/app-header';
const LIGHT_THEME = createToolkitTheme('light');
const DARK_THEME = createToolkitTheme('dark');
const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
isLoading: false,
error: null,
hitsCount: 0
};
this.handleClick = this.handleClick.bind(this);
}
componentDidMount(){
this.setState({ isLoading: true });
fetch(API + DEFAULT_QUERY)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong with the API...');
}
})
.then(data =>
this.setState({ hits: data.hits, hitsCount: 0 ,isLoading: false
}))
.catch(error => this.setState({ error, isLoading: false }));
}
handleClick(){
this.setState(prevState => ({ hitsCount: prevState.hitsCount + 1
}));
}
render() {
const { hits, hitsCount, isLoading, error } = this.state;
return (
<>
<div>
count: {hitsCount}
url: {hits[hitsCount].url}
</div>
<button onClick={this.handleClick}>GENERATE</button>
</>
);
}
}
You need to pass an onClick handler function to update a state value.
Here's a codesandbox that stores the hits array in state along with a current index, and a handler that simply increments the index.
Consider This:
Read through the comments in the code to get the updates.
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
currentHit: 0, //add a state currentHit to hold the url that is displayed by now
isLoading: false,
error: null,
};
}
componentDidMount(){
this.setState({ isLoading: true });
fetch(API + DEFAULT_QUERY)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong with the API...');
}
})
.then(data => this.setState({ hits: data.hits, isLoading: false })) //Make hits array holding all the hits in the response instead of only the first one
.catch(error => this.setState({ error, isLoading: false }));
}
handleClick = () => {
this.setState(prevState => ({
currentHit: prevState.currentHit + 1,
}));
}
render() {
const { hits, isLoading, error, currentHit } = this.state;
// pass the handleClick function as a callback for onClick event in the button.
return (
<>
<p>{hits[currentHit].url}<p/>
<button onClick={this.handleClick.bind(this)}>GENERATE</button>
</>
);
}
}
Here is the working code, on each click next url will be shown.
codesandbox link
handleChange method can work if you want to append the url from array as well. Or you could just increment the index in this function.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
state = {
data: [],
index: 0
};
componentDidMount() {
this.setState({ isLoading: true });
fetch("https://reqres.in/api/users")
.then(response => {
if (response) {
return response.json();
} else {
throw new Error("Something went wrong with the API...");
}
})
.then(data => this.setState({ data: data.data }))
.catch(error => this.setState({ error }));
}
handleChange = () => {
let i =
this.state.index < this.state.data.length ? (this.state.index += 1) : 0;
this.setState({ index: i });
};
render() {
return (
<div className="App">
<span>
{this.state.data.length && this.state.data[this.state.index].avatar}
</span>
<button onClick={this.handleChange}>GENERATE</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Calling an Api with React

So I want to call an API with react and my data is not showing up correctly I know I did it right but is there anything I am missing because I don't know why it is still showing Loading
import React from 'react';
import './App.css';
class App extends React.Component {
constructor (props) {
super(props);
this.state = {
students: [],
isLoaded: false,
error: null,
}
}
componentDidMount() {
fetch("http://localhost:3200/students")
.then(res => res.json())
.then((myresult) => {
this.setState({
isLoaded: true,
students: myresult.students,
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const {error, isLoaded, students} = this.state;
if (error) {
return <div>Error: {error.message}</div>
} else if (isLoaded) {
return <div> Loading ...</div>
} else {
return (
<ul>
{students && students.map(student => (
<li key={student._id}>
{student._id} {student.role_num}
</li>
))}
</ul>
);
}
}
}
export default App;
I am trying to display information from this URL http://localhost:3200/students
I was following this link on how to call an API https://reactjs.org/docs/faq-ajax.html
hey guys updated my code I am still getting the same issue stuck on loading I don't know whether I am passing in my data properly
I think there a couple of things going on here but main points are
its componentDidMount not MountComponent
your not setting students correctly in state
In you code above for MountComponent see that you are setting up movieItems and your state is expecting students. To solve the issue use the code below.
MountComponent = () => {
fetch("http://localhost:3200/students")
.then(res => res.json())
.then((myresult) => {
this.setState({
isLoaded: true,
students: myresult.students,
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
change this:
} else if (!isLoaded) {
to:
} else if (isLoaded) {
Write this in your function and check
componentDidMount() {
fetch("http://localhost:3200/students").then(res => {
this.setState({ students : res.data })
})
}

Access value from function dispatch on component

I'm new to react.
I have a function, that need to refresh the state according with API request result on my component.
How can i access that value?
Code (Example):
LoginComponent.js
class Login extends React.Component {
constructor(props){
super(props)
this.state = {
username : '',
password : ''
}
}
submit = (e) => {
/* console.logging "Some response"*/
console.log(this.props.doLogin(this.state))
}
render(){
return (
<form onSubmit={this.submit}>/* some login element */</form>
)
}
}
export default connect(null, {LoginAction})(Login);
LoginAction.js
export function doLogin(state){
return dispatch => {
return axios.post('login', state).then(res =>{
return "Some response";
})
}
}
you can do like this
for example create axios.js
import axios from 'axios';
var instance = axios.create({
baseURL: 'https://www.',
timeout: 1000,
headers: {'Authorization': 'Bearer xxx'}
});
export default instance;
then in your another screen
import React from 'react';
import API from '../axios';
export default class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
feedback: "",
id: "",
errors: {},
};
}
postComment = () => {
API.post(`/new-comment`, {
id: this.state.id,
feedback: this.state.feedback,
})
.then(res => res.data)
.then((response)=> {
this.setState({
feedback: '',
error: response.error || null,
})
}).catch(error => {console.log(error), this.setState({ error});});
}

Resources