I built an api that returns me the units that I have registered in a DB but when trying to return these are not reviewing
import React, { Component } from 'react';
import axios from 'axios';
const api = {
units: () => {
axios.get('http://192.168.0.23/api/public/api/units')
.then(response => {
console.log(response);
return response.data.data
}).catch((error) => {
console.log(error.message)
});
return 'Error'
},
};
export default api;
The response displays the data correctly, the response.data.data
if used in a file with a class I can set a state units = []
and with a setState
return the units
However I would like to create this file for the api returns, however as I do not use a class so I understand I can not use the state.
Is there any way of without the class returning this data, or keeping in a variable or something of the sort?
Or use setState
right here without a class?
I believe that these would be the ways to solve my problem, but if someone else knows otherwise than putting the api call in the same file as the final class may be too.
I tried that way too:
async function getUnits() {
return await axios.get('http://192.168.0.23/api/public/api/units');
}
getUnits.then((response) => {
console.log(response);
return response.data.data
}).catch((response) => {
console.log(response)
});
But the error indicated that getUnits.then is not a function
Even with a normal function did not work:
function units() {
axios.get('http://192.168.0.23/api/public/api/units')
.then(response => {
console.log(response);
return response.data.data
}).catch((error) => {
console.log(error.message)
});
return 'Error'
};
Use the following code, It will help you.
Normally we would just load the data and then render our app. But React expects some initial state for all that data and needs to update itself once that AJAX request is complete. For this reason, you need to store all that data in the app's state.
Here's how that looks:
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import axios from 'axios';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {units: []};
}
componentDidMount() {
this.getUnits();
}
getUnits() {
axios.get('http://192.168.0.23/api/public/api/units')
.then(response => {
this.setState({ units: response.data.data }));
}).catch((error) => {
console.log(error.message)
});
}
render() {
const unit = this.state.units.map((item, i) => (
<div>
<h1>{ item.example }</h1>
</div>
));
return (
<View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Units: {unit}</Text>
</View>
);
}
}
And If you want subcomponents to pass that data down to. Here's what that looks like:
const unit = this.state.units.map((item, i) => (
<div>
<h1>{ item.example }</h1>
<Test unitData={item} />
</div>
));
In different Test
component
class Test extends Component { //use the data in a class component
constructor(props) {
super(props);
}
render() {
const unit = this.props.unitData
return (
<div className="test">
<h1>{unit.example}</h1>
</div>
);
}
}
Please check example to here, which will help you to resolve your issue.
Examples:
Hope this will help you!!
I encountered this issue of async callback in my initial days of programming with javascript, where I found it very difficult to pass results between the files using pure functions. There is something I can suggest you, that you can use anywhere with async programming in javascript and has nothing to do with react.js
import React, { Component } from 'react';
import axios from 'axios';
const api = {
units: (callback) => {
axios.get('http://192.168.0.23/api/public/api/units')
.then(response => {
console.log(response);
callback(response.data.data);
}).catch((error) => {
console.log(error.message)
});
return 'Error'
},
};
export default api;
And inside your App
component:
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import api from './units';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
units: [],
};
}
//Always do async tasks(side effects) in componentDidMount, I will provide you a link to know Do's and Dont's with lifecycle hooks.
componentDidMount() {
if(this.state.units.length === 0){
api.units((data) => this.setState({units: data}));
}
}
render() {
return (
<View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Units: {this.state.units}</Text>
</View>
);
}
}
This is the way of passing a callback functions around when you deal with async operations in Javascript, as you can not return a evaluated
result from an async function, because as soon as the result is still being evaluated your function will return
something and get out of the scope
, but you can use the callback
handler of the async operation to finally update your view according to the evaluated result
. I am only handling the success
callback, you can pass error
callback as well to handle the error case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With