How to make a POST request in react native - react-native

I am trying to do an axios post in react native.
In postman, it is working but in app, it is not working. Can someone help?
var Data = {
name: name,
email: email,
};
}
axios
.post('http://10.0.2.2:8000/api/register', Data)
.then(res => {
alert(res);
})
.catch(err => console.log(JSON.stringify(err)));
}
this is the error
{"message":"Network Error","name":"AxiosError","stack":"AxiosError: Network Error\n at XMLHttpRequest.handleError (http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.sukprsavam&modulesOnly=false&runModule=true:103294:16)","config":{"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false},"adapter":["xhr","http"],"transformRequest":[null],"transformResponse":[null],"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"maxBodyLength":-1,"env":{},"headers":{"Accept":"application/json, text/plain, /","Content-Type":"application/json"},"method":"post","url":"http://103.161.55.43/api/register/","data":"{"name":"dadkn","email":"sdfgsf#gmail.com","baby_date":"27/12/2022"}"},"code":"ERR_NETWORK","status":null}

IOS and Android don't work with HTTP protocol by default. It's not secure. If you can migrate to HTTPS, all will work fine.
But you can disable this secure option by updating the following files;
Android (AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET" />
<application
//-------add this attribute-------//
android:usesCleartextTraffic="true">
</application>
IOS (Info.plist)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

Related

HTTP requests does not work on my real android device (React Native Expo Tunnel)

I'm facing this issue while posting data to my server via axios.post(). It always catches the error "Network Error" when I run my app on my real android device. But when I use an android emulator device, it works correctly and returns the response. I tried to use "ngrok http 5000" and used the uri that ngrok gave me but that didn't work either. I'm hopeless at this point because my app is using QR code scanner and indie notifications. I'm unable to test it while using emulator. Please help me!
I'm leaving my axios.post() method below
const login = async (email, password, navigation) => {
userState.loading = true;
axios
.post(`http://${localIP}:5000/api/user/login`, {
email,
password,
})
.then((response) => {
userState.loading = false;
userState.user = response.data;
console.log("Data: ", response.data);
navigation.reset({
index: 0,
routes: [{ name: "Home" }],
});
})
.catch((err) => {
userState.loading = false;
console.log("ERR :", err.message);
});
};
I tried to use "ngrok http 5000" and used the uri that ngrok given me but that didn't work either.
Might be a little light on information in order to give a definite answer, it's worth looking at installing a debugger and inspecting the network requests to see where they're going wrong. But here's a couple things to try:
In your AndroidManifest.xml file add the line: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Use http://my.local.ip:port instead of http://localhost:5000 (looks like you're doing this anyway, if not you get this via ipconfig in Command Prompt)
Try adding "Content-Type": "application/json", Accept: "application/json" headers to your Axios request

React native Linking is not working properly

I am trying to send email from my application,
This is the code:
sharePhraseToGmail = async () => {
let url = `mailto:xxx#gmail.com`
const query = qs.stringify({
subject:'xxx',
body:'xxxx',
})
if (query.length) {
url += `?${query}`;
}
try {
Linking.openURL(url)
} catch (e) {
console.log('--------e',e)
}
}
No matter what I pass, wrong or real email it gives me this error
Possible Unhandled Promise Rejection (id: 1):
Error: Unable to open URL: mailto:xxx#gmail.com?subject=xxx&body=xxxx
Or : Add mailto in info.plist
I followed the second error and updated my info.plist like this:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>mailto</string>
</array>
I also tried to use libraries such as react-native-mail and react-native-email but I got the same error on both of them.
Any suggestions on why is this happening?
React native version:0.63.4
Emulator : Iphone 11

Send plain text request body with apollo-link-rest

I am trying to send a POST request to an endpoint that takes a application/x-www-form-urlencoded Content-Type and a plain text string for the form data with the apollo-link-rest module and am having the hardest time.
In cURL form the request I want to make looks like this:
curl -X POST http://tld.com/search -d include_all=My%20Search%20Term
I have wrapped my main component in the graphql HOC from react-apollo like this.
export default graphql(gql`
mutation productSearch($input: string) {
search(input: $input) #rest(
path: "/search",
method: "post",
endpoint: "search",
bodySerializer: "search"
) {
total
}
}
`,
{
props: ({ mutate }) => ({
runSearch: (text: string) => {
if (mutate) {
mutate({
variables: {
input: `include_all=${encodeURIComponent(text)}`,
},
});
}
},
}),
})(SearchResults);
The search bodySerializer referenced in the query looks like this.
const searchSerializer = (data: any, headers: Headers) => {
headers.set('Content-Type', 'application/x-www-form-urlencoded');
return { body: data, headers };
};
And then have called the runSearch function like this in my component.
async componentDidMount() {
try {
const result = await this.props.runSearch(this.props.searchText);
} catch (error) {
// report error & show message
}
}
Now I realize I'm not doing anything with the results but there seems to be an unhandled promise rejection (that's what React Native is telling me with a yellow box warning) when running the search code. I'm examining the request with Reactotron as well and the request looks good, but it fails still. I'm wondering if I'm missing something with how I'm configuring apollo-link-rest or if there's a better way I can examine requests made from the Apollo client.
Any help here would be much appreciated. Thanks!
So it turns out that I had everything setup correctly above. Instead of it being an issue with react-apollo it was an issue with my Info.plist file. I hadn't enabled the ability of the iOS app to make HTTP requests. It was only allowing HTTPS. I fixed it with this entry in my Info.plist.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

react-native iOS Simulator Network Connection

I'm trying to fetch() some data in my react-native app and it's failing. So, I found NetInfo and I am using it when the app starts and on each MapView onRegionChangeComplete event using the iOS simulator (if it matters, iPhone5s and iPhone 6), and the status returned by NetInfo is unknown every time. The MapView works fine and I can navigate the web using Safari on the simulators. The most common issue I've found related to fetch() failing is from developers using localhost in their url. I'm using http://api.openweathermap.org/data/2.5/weather? as my url, so I'm confident this is a simulator issue. I don't have a iOS device to test on and MapView isn't available for android yet, so I can't test on android. Can someone point me in the right direction as to why?
Thank you.
PS. The fetch error I'm logging to console is - TypeError: Network request failed
Here is my code:
module.exports = function(latitude, longitude) {
var rootURL = 'http://api.openweathermap.org/data/2.5/weather?APPID=MYAPIKEY&lat=35&lon=139';
console.log(rootURL);
return fetch(rootURL) // fetch is part of react or react-native, no need to import
.then(function(response){ // method chaining used here
// Shorthand to check for an HTTP 2xx response status.
// See https://fetch.spec.whatwg.org/#dom-response-ok
if (response.ok) {
console.log('Response from fetch was ok, returning response to next then');
return response
} else {
// Raise an exception to reject the promise and trigger the outer .catch() handler.
// By default, an error response status (4xx, 5xx) does NOT cause the promise to reject!
console.log('Throwing error to .catch with statusText: ' + response.statusText);
throw Error(response.statusText);
}
})
.then(function(response) {
console.log('Returning JSON to next then')
return response.json();
})
.then(function(json) { // chain a second function when JSON is returned
console.log('Returning this json to Api call in index.os.js' + json);
return {
city: json.name,
//temperature: kelvinToF(json.main.temp),
//decription: json.weather[0].description
}
})
.catch(function (error) {
console.log('My fetch Error: ' + error + 'Specific error: ' + error.message);
})
}
2nd UPDATE: In addition to the updates and information below, I've narrowed it down to this being an iOS simulator issue. I don't have the same problem on an Android device. Again - the only time the simulator has an issue is making a fetch() request using a http: url. When I use a https: url, the simulator is happy. I also found some DEV setting in the simulator to allow http requests. This gave me no change.
UPDATE: I've narrowed the problem down to the url. If I use fetch within react-native, with this url http://api.openweathermap.org/data/2.5/weather?APPID=MYAPPKEY&lat=35&lon=139 with MYAPPKEY equaling my key, it fails. If I use the same url in my browser, it returns the json I am expecting.
Also, if I use fetch within react-native and use this url https://api.github.com/users/mralexgray/repos , I don't get the Network request failed, I get valid json.
One more interesting note - if I enter the openweathermap url in my browser, the address bar strips off the http:// part when it returns json. When I enter the github address in my browser, the address bar keeps the https://.
Another interesting note - if I use a non-https url, it fails.
If you are using react-native#0.28 or higher, in the Plist.Info the following was removed:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
And this was added :
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSAppTransportSecurity</key>
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
This is related to the ATS in iOS, look at the following link for more info.
https://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/
You basically need to add the http domains that you use to the plist.Info

React Native Fetch Request Fails

I am using the react native Fetch API to get JSON data from https://api.github.com/users/{username} but the request fails with the following error message.
"TypeError: Network request failed {stack: (...), message: 'Network
request failed'}".
I believe for https, sometimes you get NSURLAuthenticationChallenge. I am not sure how to implement this. Anyone have any idea about this?
If you are using iOs you may need to do the following:
You must enable your AppTransportSecurity
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
or
in the Info.plist.
For Android ensure that you have added permission to use INTERNET in the AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET" />
Can you provide an snippet of your fetch code?
Generally, a fetch statement is written like:
fetch(requestURL)
.then( (response) => response.json() )
.then( (data) => {
this.setState({data: data});
})
.catch( (error) => console.log(error) )
.done();
Catching the error will allow the program to proceed without crashing.
In my case the issue wasn't in the code. I started emulator when had no network. After I logged in to wifi point network on emulator still wasn't functioning. I restarted emulator - all worked.
So:
Connect to network.
Restart emulator.
If it doesn't help, then check your code.
I was also having this issue React Native Fetch Request Fails very frequently.
In my case the response from the API call was around 5kb , so i removed the unnecessary data from the API response and reduced the result size to around 1kb and all started working.
So try to limit the data you are requesting from the API.
Have you tried XMLHttpRequest?
As demonstrated in the doc, https is supported by XMLHttpRequest:
var request = new XMLHttpRequest();
request.onreadystatechange = (e) => {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
console.log('success', request.responseText);
} else {
console.warn('error');
}
};
request.open('GET', 'https://mywebsite.com/endpoint.php');
request.send();