got "undefined" when fetching from api other than https://facebook.github.io/react-native/movies.json - react-native

I follow this https://facebook.github.io/react-native/docs/network.html#using-fetch to learn how to fetch data from a remote api and it is working great. However, whenever I change the url https://facebook.github.io/react-native/movies.json of that example to another public api, I got "undefined" in my debugger and no data to display. Even the NASA API is returning that.
Any Idea?
const apiHost1 = 'https://facebook.github.io';
const apiHost2 = 'http://countryapi.gear.host';
const apiHost3 = 'https://api.nasa.gov';
export default {
async fectchInitialOrders(){
try {
let response = await fetch(apiHost1 + '/react-native/movies.json');
let responseJson = await response.json();
return responseJson.movies;
} catch (error) {
console.error(error);
}
},
async fectchInitialCountry(){
try {
let response = await fetch(apiHost2 + '/v1/Country/getCountries/');
let responseJson = await response.json();
return responseJson.movies;
} catch (error) {
console.error(error);
}
},
async fectchNasaData(){
try {
let response = await fetch(apiHost3 + '/planetary/apod?api_key=NNKOjkoul8n1CH18TWA9gwngW1s1SmjESPjNoUFo');
let responseJson = await response.json();
return responseJson.movies;
} catch (error) {
console.error(error);
}
}
};
Only the facebook one is returning data

I'm hitting the NASA API from the url that you have used and there is no key called 'movies' in the response. You are trying to access the movies key from the NASA API response which doesn't exist which is why you are probably getting the error.

Related

In reactnative expo I tried using secureStore from expo in redux to save token the one I get from api

I tried using redux to save token the one I get from api in react native ..its working now.
First one is for settoken and other one is for gettoken.
enter image description here
export const verifyOTP = (formValues, actions) => {
return async (dispatch) => {
dispatch(startSubmitting());
const url = `/validate-otp`;
var formdata = new FormData();
formdata.append("mobile", formValues.mobile);
formdata.append("otp", formValues.otp);
const response = await api.post(url, formdata);
dispatch({
type: "VERIFY_OTP",
payload: response,
});
dispatch(stopSubmitting());
await SecureStore.setItemAsync("userToken", response.data.access_token);
};
};
export const checkUser = () => {
return async (dispatch) => {
const token = await SecureStore.getItemAsync("userToken");
const url = `/me`;
const response = await api
.post(url, { token })
.then((res) => {
return res;
})
.catch((error) => {
return error.response;
});
dispatch({
type: "CHECK_USER",
payload: response,
});
};
};
The Problem
you are mixing two different implementations in checkUser to handle a promise which is clearly incorrect and leads to the issues.
The Solution
since your other parts of codes use the async/await so try to remove then/catch block from the response constant:
const checkUser = () => {
return async (dispatch) => {
const url = '/me';
try {
const token = await SecureStore.getItemAsycn("userToken);
const response = await api.post(url, {token})
dispatch({type: "CHECK_USER", payload: response})
} catch (error) {
// to proper action on failure case
}
}
}
Note 1: always use async/await in try/catch block. more on MDN documentation.
Optional
since you are trying to call two async actions (once for getting token and once for calling '/me' API), I encourage you to use two different try/catch blocks to handle the failure case for each async action separately. for example:
const checkUser = () => {
return async (dispatch) => {
let token = null;
try {
token = await SecureStore.getItemAsync("userToken");
} catch (err) {
// proper action in case of failure on getting the token from storage
}
// you may need to ignore API calls without the token, so:
try {
if(token){
const url = '/me';
const response = await api.post(url, {token});
dispatch({type: "CHECK_USER", payload: response});
}
} catch (err) {
// take proper action with the error response according to your applicaiton
}
}
}

Error loading preview in Firebase Storage

This is my function put
var metadata = {
contentType: 'image/png'
}
const task = fireStore.ref(fileName).put(uploadUri, metadata)
try {
await task
setUpLoading(false)
} catch(err) {
console.log(err)
}
but it didn't work.
Thanks for help.
I found solution for it.
let newImageUri
try {
const response = await fetch(imageUrl)
const blob = await response.blob()
await firebase.storage().ref().child(fileName).put(blob)
var ref = firebase.storage().ref().child(fileName).put(blob)
newImageUri = await ref.snapshot.ref.getDownloadURL()
} catch (error) {
console.log(error)
}

Error handling in Express using Axios for API call

I am trying to set up a basic express app to get some API data using axios. I want to do things the right way but I am a bit lost with error handling. Ideally, if there is an error I want to communicate it to users which I could do if the API call was within it the route. But how do you do it if it's a separate function?
axios call function using async:
const getForm = async () => {
try {
const config = {
method: 'get',
url: 'https://api.something.org/niceform'
}
}
const response = await axios(config)
return response
} catch (error) {
return error.message
}
}
express route:
app.get('/niceform', async (req, res) => {
try {
const data = await getForm()
res.send(data)
} catch (error) {
???
}
})
If I understand it correctly the getForm() function will return either the response or the error and then the route will send whatever comes back. But then what does the route's catch block do and how should I use it?
Is this setup considered to be a good practice?
Any advice would be appreciated, I am still learning.
The catch block can be removed from the getForm function. An error will be caught anyways in the get route.
const getForm = async () => {
const config = {
method: 'get',
url: 'https://api.something.org/niceform'
};
const response = await axios(config);
return response;
}
Or the error can be caught inside getForm, in order to do something in that catch block, and be thrown:
const getForm = async () => {
const config = {
method: 'get',
url: 'https://api.something.org/niceform'
};
try {
const response = await axios(config);
return response;
} catch (err) {
// log the error
// add extra information to the error
// else
// (see the attached answer)
throw err;
}
}
Consequently, in the catch block in the get route, an error can be responded:
app.get('/niceform', async (req, res) => {
try {
const data = await getForm();
res.send(data);
} catch (error) {
res.error(error);
}
})
Reference:
https://stackoverflow.com/a/42171508/3563737
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw

React Native, fetch after async function

I have a problem that I do not know how to solve...
I have an api token saved in AsyncStorage, and when I want do fetch to rest I need this api token, but I do not know how to do it.
I have file Functions.js with AsyncStorage functions.
async retrieveItem(key) {
try {
const retrievedItem = await AsyncStorage.getItem(key);
const item = JSON.parse(retrievedItem);
return item;
} catch (error) {
console.warn(error.message);
}
},
getApiToken: function(){
try {
return Functions.retrieveItem('api_token');
} catch (error) {
console.warn(error.message);
}
},
File with fetch functions. (Api.js)
I tested with an asynchronous function, but not found...
async get(url) {
try {
var api = await Functions.getApiToken();
if (!api)
api = "";
let opt = {
method: 'get',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
}),
};
return fetch(baseUrl + url + api, opt);
} catch (error){
console.warn(error);
}
},
When I did the fetch function, it worked for me without problems
And the screen file Home.js
componentDidMount() {
Api.get('home').then( response => {
this.setState({
profiles: response.profiles,
});
});
}
Please modify your Functions.js code a bit -
async retrieveItem(key) {
try {
const retrievedItem = await AsyncStorage.getItem(key);
const item = JSON.parse(retrievedItem);
return item;
} catch (error) {
console.warn(error.message);
}
},
async getApiToken{
try {
let token = await retrieveItem('api_token');
return token;
} catch (error) {
console.warn(error.message);
}
}
Hope this helps you!

react native AsyncStorage not working?

for setting the item i am using this first code.
console.log(ACCESS_TOKEN);
console.log(typeof(ACCESS_TOKEN));
async function setToken() {
try {
await AsyncStorage.setItem('access_token', ACCESS_TOKEN);
} catch (error) {
console.log("token not set")
}
}
setToken();
for getting the item , i am using this code
componentWillMount(){
async function getToken() {
try {
const value = await AsyncStorage.getItem('access_token');
if (value !== null){
console.log(value);
this.setState({ access_token: value });
}
} catch (error) {
console.log( "Error retrieving data")
}
}
getToken();
the result i am getting in first code is
1a61b72b-ee83-43de-9cf9-3fa270ce694d
string
but getting nothing at console at getting code . why ?
You can try this one:
set item using this
AsyncStorage.setItem('access_token', ACCESS_TOKEN);
get item using this
try {
AsyncStorage.getItem('access_token')
.then((value) => {
if (value) {
// you will get your access_token here
}
}).done();
} catch (error) {
console.log(error); // you will get error here
}
To set the item
AsyncStorage.setItem('access_token', ACCESS_TOKEN)
.then(() => {
//your success code
})
.catch((error) => {
//your failure code
})
To get the item
AsyncStorage.getItem('access_token')
.then(access_token=> {
//you will be getting the access token here
})
.catch(err => {
//handle the error
})
Maybe this is what you intended:
async function getToken() {
try {
const value = await AsyncStorage.getItem('access_token');
if (value !== null){
console.log(value);
this.setState({ access_token: value });
}
} catch (error) {
console.log( "Error retrieving data")
}
}
componentWillMount(){
getToken();
}
If instead your code is getting stuck while working with AsyncStorage, there's a well known bug reproducible only in development: https://github.com/facebook/react-native/issues/12830
They only way to bypass it, afaik, it is just to restart the debugger when you get stuck
Remember that setting state during componentWillMount is not the correct way to do it. You should use the constuctor for that
My answer might not directly apply to your case, But I had the same problem as you did with AsyncStorage and It was getting stuck, so this might help other people.
As stated in this answer:
AsyncStorage only takes string as a value and key.
But I was accidentally giving it null (which as you know is considered an object) so it got stuck. So check if you are passing a string value as both the first and second argument to setItem.