react native use navigation prop in fetch - javascript

I am pretty new to react native. I am using react navigation in my react-native app. I am passing some props from one screen to another, and I need to use one of the props in a fetch I am trying to execute within the componentDidMount lifecycle method. With everything I have tried, it sends the value for the "type" key, but it sends nothing for the "location" key (see code below). Could someone help me with what am I missing or doing wrong? I have tried several things to pass the prop but nothing has worked yet.
componentDidMount() {
const { params } = this.props.navigation.state;
var data = {
type: 'r',
location: params.location
}
return fetch('http://myapisite', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});
}

I was able to resolve the issue. I am not 100% certain why what I had didn't work, but when I changed it to the following, it worked as expected:
const {state} = this.props.navigation;
var data = {
type: 'restaurant',
location: state.params.location
}
return fetch('http://mylink', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});

Related

How to fix Maximum update depth exceeded Error occuring in ComponentWillMount?

I have searched this issue, but related cases to this issue are not same as mine.
I have React client side where Im using react-big-scheduler. In ComponentDidMount I have to do API axios calls and set state with response data.
componentWillMount() {
let today = moment().format(DATE_FORMAT);
let schedulerData = new SchedulerData(today, ViewTypes.Week);
schedulerData.localeMoment.locale('en');
const token = localStorage.getItem("jwttoken");
axios.post('http://localhost/Auth/api/validate.php', {
"jwt": token
}, {
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
}
})
.then(response => {
console.log(response.data);
this.setState({
vendor: response.data.data
})
const vid = response.data.data.VendorID;
return axios.get('http://localhost/Auth/api/show_all_HR.php?VendorID=' + vid, {
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
}
})
.then(response => {
console.log(response.data);
schedulerData.setResources(response.data);
this.setState({
AllHR: response.data,
viewModel: schedulerData
});
console.log("I should be rendered at 1st", this.state.AllHR);
console.log(vid);
});
});
axios.get('http://localhost/Auth/api/show_one_HR_hours.php?VendorID=48', {
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
}
})
.then(response => {
console.log(response.data);
schedulerData.setEvents(response.data);
this.setState({
AllSlots: response.data,
viewModel: schedulerData
});
});
}
Now I get this Error for doing setState:
Maximum update depth exceeded. This can happen when a component
repeatedly calls setState inside componentWillUpdate or
componentDidUpdate. React limits the number of nested updates to
prevent infinite loops.
Now All other solutions suggest that problem occurs when we call the function in onClick or put the () after function. But I have no such thing.
So Please suggest me what to change in my code?
EDIT:
I render it like this:
render() {
const {viewModel} = this.state;
return (
<div>
<Row style={ {width: "100%"}}>
<h3> Schedule Maintenance Service Time Slots</h3>
<Scheduler schedulerData={viewModel}
prevClick={this.prevClick}
nextClick={this.nextClick}
onSelectDate={this.onSelectDate}
onViewChange={ this.onViewChange}
eventItemClick={this.eventClicked}
viewEventClick={this.ops1}
viewEventText="Ops 1"
viewEvent2Text="Ops 2"
viewEvent2Click={this.ops2}
updateEventStart={this.updateEventStart}
updateEventEnd={this.updateEventEnd}
moveEvent={this.moveEvent}
newEvent={this.newEvent}
leftCustomHeader={leftCustomHeader}
toggleExpandFunc={this.toggleExpandFunc}
/>
</Row>
</div>
);
}
prevClick = (schedulerData) => {
schedulerData.prev();
schedulerData.setEvents(this.state.AllSlots);
this.setState({
viewModel: schedulerData
})
}
nextClick = (schedulerData) => {
schedulerData.next();
schedulerData.setEvents(this.state.AllSlots);
this.setState({
viewModel: schedulerData
})
}
onViewChange = (schedulerData, view) => {
schedulerData.setViewType(view.viewType, view.showAgenda, view.isEventPerspective);
schedulerData.setEvents(this.state.AllSlots);
console.log("Im changing VIEW");
}

How to import external data fetch api into react componentDidMount method

I'm trying to consolidate some code in one of my react components because my componentDidMount method is getting a bit verbose. This gave me the idea to create an api that does all of my data fetching for the entire app.
I'm having an asynchronous issue I'm not sure how to resolve.
I created the separate api file (blurt.js):
exports.getBlurts = function() {
var blurtData = null;
fetch('/getblurts/false', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then((data) => {
blurtData = data;
});
return blurtData;
}
and imported it to my (.jsx) component via
import blurtapi from '../api/blurt.js';
The problem is that when I call blurtapi.getBlurts() within componentDidMount(), the value comes back as null. However, if I write the data to the console like so:
.then((data) => {
console.log(data);
});
all is as it should be. So, the function is returning before the db operation completes, hence the null value. How would I reign in the asynchronous aspect in this case? I tried an async.series([]) and didn't get anywhere.
Thanks
So fetch returns a promise, which it is async , so any async code will run after sync code. so this is the reason you get null at first.
However by returning the async function , you are returning a promise.
Hence this code:
exports.getBlurts = async () => {
const data = await fetch('/getblurts/false', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
const jsonData = await data.json();
return jsonData;
}
To retrieve any promise data, you need the then function,
so in your componentDidMount, you will do:
componentDidMoint() {
blurtapi.getBlurts()
.then(data => console.log(data)) // data from promise
}
Promises:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
async/await:
https://javascript.info/async-await
I hope this makes sense.
fetch call returns a promise. therefore in your function u do something like this
exports.getBlurts = function() {
var blurtData = null;
return fetch('/getblurts/false', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
}
And do this in your componentDidMount
componentDidMount(){
blurtapi.getBlurts().then((data)=>{
this.setState({data})
}
}
In your example return blurtData; line will run synchronously, before the promise is resolved.
Modify getBlurts as:
exports.getBlurts = function() {
return fetch('/getblurts/false', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then((data) => {
return data;
});
}
And in componentDidMount:
componentDidMount() {
getBlurts.then((data) => {
// data should have value here
});
}
exports.getBlurts = function() {
return fetch('/getblurts/false', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(res => return res)
async componentDidMount() {
const response = await blurtapi.getBlurts();
}
or
exports.getBlurts = function() {
return fetch('/getblurts/false', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => res.json())
componentDidMount() {
const data = blurtapi.getBlurts()
.then(data => {
// Do something or return it
return data;
});
}

How to perform multiple API calls inside ComponentDidMount using fetch in React-Native?

In my componentDidMount function I call AsyncStorage to get some saved value and then make a GET request and fetch data like below:
componentDidMount() {
AsyncStorage.getItem("token").then(value => {
const url = 'my url';
console.log('token:' + value)
return fetch(url, {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json',
'token': 'abcd',
'jwt': value
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
dataSource: responseJson,
isLoading: false,
getValue: value
})
})
.catch((Error) => {
console.log(Error)
})
})
}
Now, I need to make another GET request. Suppose if I want to make the same request again in this function , how can I do that?
I solved it very easily from the suggested comments. I did the API call part in two different functions and then called these two functions inside ComponentDidMount like below code-
getFirstApiResposnse() {
AsyncStorage.getItem("token").then(value => {
const url = 'my url';
console.log('token:'+ value)
return fetch(url, {
method: 'GET',
headers: new Headers({
'Content-Type' : 'application/json',
'token': 'abcd',
'jwt': value
})
})
.then((response)=> response.json() )
.then((responseJson) => {
this.setState({
dataSource: responseJson,
isLoading: false,
getValue: value
})
})
.catch((Error) => {
console.log(Error)
});
}
)
};
getSecondApiResponse() {
AsyncStorage.getItem("token").then(value => {
const url = 'my url';
console.log('token:'+ value)
return fetch(url, {
method: 'GET',
headers: new Headers({
'Content-Type' : 'application/json',
'token': 'abcd',
'jwt': value
})
})
.then((response)=> response.json() )
.then((responseJson) => {
console.log('####:'+responseJson.cat_note)
this.setState({
isLoading: false,
getValue: value,
})
})
.catch((Error) => {
console.log(Error)
});
}
)
}
componentDidMount() {
this.getFirstApiResponse();
this.getSecondApiResponse();
}
You can also use Promise.all(). Which comes handy with multiple requests. Also, we can use helper library such as async and use its forEach, waterFall, series, parallel, etc methods depending on project needs. These things make our code more readable and scalable.

react access API response

Action:
export const filesDownload = postData => (dispatch) => {
console.log(postData);
fetch(`http://${ip}:8000/api/v1/integrator/email/need_attachment/`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(postData),
})
.then(res => console.log(res.json()))
.then(files =>
dispatch({
type: GET_FILES,
payload: files,
}));
};
Reducer:
case GET_FILES :
return{
...state,
file: action.payload
}
Component:
OnEnableDisplay = (event) => {
this.props.filesDownload(attachements_call);
};
Above is my code I want to access the response from the API which I get in the action in the component and set the state again so that I can show the data I get.
I am new to redux, please spare a little time to help guys.

Axios post stay on pending

This is a simple Post request using Axios inside Vue:
import axios from 'axios'
export default {
name: 'HelloWorld',
props: {
msg: String
},
mounted () {
const code = 'test'
const url = 'http://localhost:3456/'
axios.post(url, code, { headers: {'Content-type': 'application/x-www-form-urlencoded', } }).then(this.successHandler).catch(this.errorHandler)
},
methods: {
successHandler (res) {
console.log(res.data)
},
errorHandler (error) {
console.log(error)
}
}
}
The Get method works fine. But Post stay as "Pending" on Network tab. I can confirm that there is a Post method on my webservice and it return something (tested on Postman).
UPDATE
Sending code as a param:
axios(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
params: {
code : 'test'
},
}).then(this.successHandler).catch(this.errorHandler)
WEBSERVICE
server.post('/', (req, res, next) => {
const { code } = req.params
const options = {
validate: 'soft',
cheerio: {},
juice: {},
beautify: {},
elements: []
}
heml(code, options).then(
({ html, metadata, errors }) => {
res.send({metadata, html, errors})
next()
})
})
I think there's issue with your axios request structure.
Try this:
const URL = *YOUR_URL*;
axios(URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
data: *YOUR_PAYLOAD*,
})
.then(response => response.data)
.catch(error => {
throw error;
});
If you're sending a query param:
axios(URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
params: {
code: 'your_string'
},
})
if it is path variable you can set your url:
const url = `http://localhost:3456/${code}`
Let me know if the issue still persists
I also was facing the same. Network call was pending all the time and Mitigated it by passing the response back from server.js(route file) e.g(res.json(1);) and it resolved the issue

Categories