I'm trying to fetch data inside object, but my object shows whole function. Why doesn't it show only my return statement? What's the way to handle this problem?
const fetchContacts = async () => {
try {
await axios.get(url, {
headers: {
'auth': 'asdsdfasfd'
}
}).then(resp => {
const newRows = resp && resp.data && resp.data.map(row =>
({
name: row.name,
surname: row.surname,
city: row.city,
familyNumber: async () => {
try {
const resp = await axios.get(url, {
headers: {
'auth': 'asdsdfasfd'
}
})
return resp.data.length
} catch(error) {
return error
}
},
})
)
})
} catch(error) {
return error
}
}
You are using async/await. You don't have to use the promise returned by .then. Try something like this. I haven't tested the code.
const fetchContacts = async () => {
try {
const resp = await axios.get(url, {
headers: {
'auth': 'asdsdfasfd'
}
});
const resNo = await axios.get(url2, {
headers: {
'auth': 'somethingNew-qednken'
}
});
const newRows = resp.data && resp.data.map(row =>
({
name: row.name,
surname: row.surname,
city: row.city,
familyNumber: resNo.data.length || 0
})
);
//console.log("my newRows : ", newRows);
} catch(err) {
console.log(err);
}
}
Related
I'm trying to store and get data that I fetch from an API. The user is supposed to get a token on the login screen, and the token will be shown in an Alert dialog on home screen when the user press a button. But the token is not shown in the Alert dialog. the token is shown after I reload(not refresh the app. I used Live Server extension) the screen three times.
Login.js
const _userLogin = () => {
fetch(URLs._login, {
method: "POST",
headers, body,
})
}).then((response) => response.json())
.then((result) => {
if(result.message !== "Unauthorized / Access Token Expired" && result.message !== "The given data was invalid."){
storeData(result.access_token, result.token_type);
navigation.navigate('HomeScreen');
} else {
Alert.alert("Error", result.message);
}
});
};
const storeData = async (accessToken, tokenType) => {
try {
await AsyncStorage.setItem('#access_token', accessToken);
await AsyncStorage.setItem('#token_type', tokenType);
await AsyncStorage.setItem('#user_auth', tokenType + " " + accessToken);
} catch (e) {
console.log(e);
}
}
Home.js [UPDATE]
const [inputs, setInputs] = React.useState({
userToken: '',
userPointsBalance: '',
expiringOn: '',
});
useEffect (() => {
_dashboard();
})
const getToken = async () => {
inputs.userToken = await AsyncStorage.getItem('#user_auth');
}
const _dashboard = () => {
getToken();
fetch(URLs._dashboard, {
method: "GET",
headers: {
'Authorization': inputs.userToken,
'Content-Type': 'application/json',
},
}).then((response) => response.json())
.then(async (result) => {
storeData(result.code, result.name, result.member_name, result.user_points_balance, result.expiring_on, result.status, result.token_id);
getData();
});
};
const storeData = async (code, name, memberName, userPointsBalance, expiringOn, status, tokenId) => {
try {
await AsyncStorage.setItem('#user_points_balance', userPointsBalance.toString());
await AsyncStorage.setItem('#expiring_on', expiringOn.toString());
} catch (e) {
console.log(e);
}
}
const getData = async () => {
const userPointsBalance = await AsyncStorage.getItem('#user_points_balance');
const expiringOn = await AsyncStorage.getItem('#expiring_on');
setInputs({userPointsBalance: userPointsBalance, expiringOn: expiringOn});
}
return (
<Text>{inputs.expiringOn}<Text>
)
i hope it works
.then(async(result) => {
if(result.message !== "Unauthorized / Access Token Expired" && result.message !== "The given data was invalid."){
await storeData(result.access_token, result.token_type)
.then(res=>
navigation.navigate('HomeScreen')
)
} else {
Alert.alert("Error", result.message);
}
});
I'm working on coinmarketcap.com api and I need only name and price and save to Mongo. It is working but at the end undefined value returned. Price value is under the quote. What is wrong ?
const axios = require('axios');
let response = null;
new Promise(async (resolve, reject) => {
try {
response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': 'myKey',
},
});
} catch(ex) {
response = null;
console.log(ex);
reject(ex);
}
if (response) {
const coin = response.data;
console.dir(coin, { depth: null });
console.log(coin.data.map(a => { a.name, a.quote.price}));
resolve(coin);
}
}
);
You shuldn't be wrapping this in another Promise (see: What is the explicit promise construction antipattern and how do I avoid it?) , just make a method which is async
async function getCoin(){
try {
const response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': 'YOURKEY',
},
});
const coin = response.data;
console.dir(coin, { depth: null });
return coin;
} catch(ex) {
console.log(ex);
throw ex;
}
}
quote contains prices identified by their keys like this:
"quote": {
"USD": {
"price": 42177.91536878145,
"volume_24h": 18068350418.6717,
"volume_change_24h": 8.1323,
"percent_change_1h": -0.02144759,
"percent_change_24h": -0.48235688,
"percent_change_7d": -0.65364542,
"percent_change_30d": -1.87762517,
"percent_change_60d": -13.80076009,
"percent_change_90d": -30.24448455,
"market_cap": 799599134284.9932,
"market_cap_dominance": 42.7605,
"fully_diluted_market_cap": 885736222744.41,
"last_updated": "2022-02-14T09:35:00.000Z"
}
}
so in order to solve the bug, you need to specify the proper key here (USD for example):
I tested this code and it works please copy it inside the separate js file and check the result(Replace your API key):
const axios = require('axios');
let response = null;
async function getCoin(){
try {
const response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': 'KEY',
},
});
const coin = response.data;
const result = coin.data.map(a => ({ name: a.name, price: a.quote['USD'].price}))
console.log(result)
return coin;
} catch(ex) {
console.log(ex);
throw ex;
}
}
getCoin()
const axios = require("axios");
async function fetchData() {
try {
const response = await axios.get(
"https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2",
{
headers: {
"X-CMC_PRO_API_KEY": "myKey",
},
}
);
return [response, null];
} catch (error) {
return [null, error];
}
}
// in your calling function code base
const [response,error] = await fetchData()
if(response){
// handle response object in calling code base
const coin = response.data
}
if(error){
// handle error explictly in calling code base
}
Getting price in quote.USD or quote['USD'] and also need to return object of name and price using map.
So Try this:
const axios = require('axios');
let response = null;
new Promise(async (resolve, reject) => {
try {
response = await axios.get('https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?limit=2', {
headers: {
'X-CMC_PRO_API_KEY': '5345bcb4-0203-4374-bef6-d67a89a6d216',
},
});
if (response) {
const coin = response.data;
cointData = coin.data.map(a => ({ name: a.name, price: a.quote.USD.price }))
resolve(cointData);
}
} catch (ex) {
response = null;
console.log(ex);
reject(ex);
}
});
I would like once the user click on the submit button for the whole "page" to reload and the useEffect function to be called. The current behavior is that when the user clicks the submit button, the useEffect function is not called at all. It is as if it does not reload directly after submission. I don't know if this is due to async and await. I give you the code :
useEffect() :
useEffect(() => {
console.log('test useEffect');
(async () => {
try {
const value = await AsyncStorage.getItem('authToken_Lust');
if(value !== null) {
const decodedValue = jwt_decode(value);
const current_time = Date.now() / 1000;
if(decodedValue.exp < current_time) {
setMessage('Vous n\'êtes plus connecté(e).')
} else {
setMessage('Vous êtes connecté(e)');
}
}
} catch(err) {
console.log(err);
}
})();
}, []);
The code of the function called after the user clicks submit :
const onSubmit = async () => {
setLoading(true)
await fetch('http://192.168.1.36:3000/api/users/login', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: email,
password: password
})
})
.then((response) => response.json())
.then(async (res) => {
if(res.error) {
setMessage(res.error);
} else {
try {
await AsyncStorage.setItem('authToken_Lust', res.token);
} catch (err) {
console.log(err);
}
}
})
.catch((err) => console.log(err))
.finally(() => setLoading(false));
}
Tanks
Create a state variable to indicate that credentials have been successfully submitted (within this component).
const [submitted, setSubmitted] = useState(1);
Alter this state variable whenever you get a response from your api in onSubmit (to somehow update the component):
try {
await AsyncStorage.setItem('authToken_Lust', res.token);
setSubmitted(submitted+1);
}
Remove the dependency array from your useEffect altogether or change it to respond to submitted value changes;
useEffect(() => {
// ...
}, [submitted]);
you need to make these changes to your codes:
const onSubmit = () => {
setIsSubmitted(true);
setLoading(true);
fetch("http://192.168.1.36:3000/api/users/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email,
password: password,
}),
})
.then((response) => response.json())
.then(async (res) => {
if (res.error) {
setMessage(res.error);
} else {
try {
await AsyncStorage.setItem("authToken_Lust", res.token);
} catch (err) {
console.log(err);
}
}
})
.catch((err) => console.log(err))
.finally(() => setLoading(false));
};
const asyncEffect = async () => {
try {
const value = await AsyncStorage.getItem("authToken_Lust");
if (value !== null) {
const decodedValue = jwt_decode(value);
const current_time = Date.now() / 1000;
if (decodedValue.exp < current_time) {
setMessage("Vous n'êtes plus connecté(e).");
} else {
setMessage("Vous êtes connecté(e)");
}
}
} catch (err) {
console.log(err);
}
};
useEffect(() => {
if (isSubmitted) {
console.log("test useEffect");
asyncEffect();
}
}, [isSubmitted]);
I changed all my code taking into account your advice that gives :
const [submitted, setSubmitted] = useState(1);
useEffect(() => {
console.log("test useEffect");
asyncEffect();
}, [submitted]);
const asyncEffect = async () => {
try {
const value = await AsyncStorage.getItem("authToken_Lust");
if (value !== null) {
const decodedValue = jwt_decode(value);
const current_time = Date.now() / 1000;
if (decodedValue.exp < current_time) {
setMessage("Vous n'êtes plus connecté(e).");
} else {
setMessage("Vous êtes connecté(e)");
}
}
} catch (err) {
console.log(err);
}
};
const onSubmit = () => {
setSubmitted(submitted+1);
setLoading(true);
fetch("http://192.168.1.36:3000/api/users/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email,
password: password,
}),
})
.then((response) => response.json())
.then(async (res) => {
if (res.error) {
setMessage(res.error);
} else {
try {
await AsyncStorage.setItem("authToken_Lust", res.token);
} catch (err) {
console.log(err);
}
}
})
.catch((err) => console.log(err))
.finally(() => setLoading(false));
};
When I click on the submit button, the console log works fine (I get "test useEffect" on console) but the asyncAffect() function does not seem to be called.
The setMessage in asyncEffect () don't change at all.
I'm making an API request with Frisbee:
const Frisbee = require('frisbee')
const api = new Frisbee({
baseURI: 'http://192.168.1.8:4000',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
export const handleSubmit = async (values): void => {
Toast.show('Uploading Product', {
duration: 3000,
position: 30,
shadow: true,
animation: true,
hideOnPress: true,
delay: 0
})
try {
const response = api.post('/products', {
body: encodeAddProductAction(values)
})
if (response.err) throw response.err
console.log(response)
} catch (err) {
console.error(err)
}
}
export const encodeAddProductAction = (values: any) => {
const submitPayload = Object.assign({}, values)
Object.keys(submitPayload).forEach((key) => {
if (key != 'Categories') {
submitPayload[key] = encodeURIComponent(
JSON.stringify(submitPayload[key])
)
} else {
// values[key] = JSON.stringify(values[key])
submitPayload[key] = submitPayload[key].join(',')
}
})
return submitPayload
}
It console logs this:
Why is my API response body buried in some strange fields like _55?
My response is:
You are using async but you are not awaiting response, that's why you get Promise returned.
try {
const response = await api.post('/products', {
body: encodeAddProductAction(values)
})
if (response.err) throw response.err
console.log(response)
} catch (err) {
console.error(err)
}
Async by default returns a Promise.
I would like to refactor the fetchRelationships function to use async await. I am not sure what the best way is to do it as this code contains nested .then at response.json().then((json) =>....
Could sby pls post the refactored version?
export const fetchRelationshipsError = (error) => {
return {
type: FETCH_RELATIONSHIPS_FAILURE,
payload: { error }
};
};
export const fetchRelationshipsRequest = () => {
return { type: FETCH_RELATIONSHIPS_REQUEST };
};
export const fetchRelationshipsSuccess = (relationships) => {
return {
type: FETCH_RELATIONSHIPS_SUCCESS,
payload: relationships
};
};
export const fetchRelationships = (url) => {
return (dispatch) => {
dispatch(fetchRelationshipsRequest());
fetch(url, config)
.then((response) => {
const responseObj = {
response: response,
payload: response.json().then((json) => {
return { body: json }
})
};
if (!response.ok) {
const error = new Error(response.statusText);
responseObj.payload.then((response) => {
show_error_alert(response.body);
dispatch(fetchRelationshipsError(response.body));
});
throw error;
}
return responseObj.payload;
})
.then((response) => {
dispatch(fetchRelationshipsSuccess(response.body))
})
.catch((error) => { console.log('Request failed', error); });
};
};
Solution:
export const fetchRelationships = (url) => {
return async (dispatch) => {
dispatch(fetchRelationshipsRequest());
try {
const response = await fetch(url, config);
const jsonResponse = await response.json();
if (!response.ok) {
show_error_alert(jsonResponse);
dispatch(fetchRelationshipsError(jsonResponse));
const error = new Error(response.statusText);
throw error;
}
dispatch(fetchRelationshipsSuccess(jsonResponse));
} catch(error) {
console.log('Request failed', error);
}
};
};
Ill take a stab at this:
export const fetchRelationshipsError = (error) => {
return {
type: FETCH_RELATIONSHIPS_FAILURE,
payload: { error }
};
};
export const fetchRelationshipsRequest = () => {
return { type: FETCH_RELATIONSHIPS_REQUEST };
};
export const fetchRelationshipsSuccess = (relationships) => {
return {
type: FETCH_RELATIONSHIPS_SUCCESS,
payload: relationships
};
};
export const fetchRelationships = (url) => {
return async (dispatch) => {
dispatch(fetchRelationshipsRequest());
try{
const response = await fetch(url, config)
const jsonResponse = await response.json()
if(!response.ok){
show_error_alert(jsonResponse);
dispatch(fetchRelationshipsError(jsonResponse));
const error = new Error(response.statusText);
throw error;
}
dispatch(fetchRelationshipsSuccess(jsonResponse));
}catch(error){
console.log('Request failed', error);
}
};