Chaining async functions doesn't work correctly - javascript

I'm trying to chain two async functions but it seems that the second one is being executed before the first one.
Here is my code
function performAction(e) {
const ZIP = document.getElementById('zip').value;
const fellings = document.getElementById('feelings').value;
console.log(`${baseURL}${ZIP},us&appid=${key}`);
getWeather(baseURL, ZIP, key,).then((data) => {
postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(
updateUI()
)}
and This is getWeather()
const getWeather = async(baseURL, ZIP, key) => {
let URL = `${baseURL}${ZIP}&appid=${key}`;
const res = await fetch(URL)
try{
const data = await res.json();
return data;
}catch(error){
console.log("error", error);
}}
and this is postData() which is supposed to execute after the getWeather function is excuted but it isn't.
const postData = async ( url = '', data = {}) => {
console.log(`This is what we fetch ${data.temperature}`);
console.log(`This is what we fetch ${data.date}`);
console.log(`This is what we fetch ${data.userResponse}`);
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
// Body data type must match "Content-Type" header
body: JSON.stringify(data),
});
try {
const newData = await response.json();
console.log(`This is the new Data ${newData.temperature}`);
return newData;
}catch(error){
console.log("error", error);
}}
and this is updateUI()
const updateUI = async () => {
const request = await fetch('/getweather');
try{
const allData = await request.json();
console.log('Get request');
document.getElementById('date').innerHTML = allData.date;
document.getElementById('temp').innerHTML = allData.temperature;
document.getElementById('content').innerHTML = allData.userResponse;
}catch(error){
console.log("error", error);
}}
What happens is that the UI gets updated first so it gets the value of undefined for the first time, and when I reload the page and enter new data the UI get's updated with the data from last time.

You need to return the promise returned from postData:
getWeather(baseURL, ZIP, key,).then((data) => {
return postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(() => {
return updateUI()
})
Another way you could write this is like this:
async function run() {
await getWeather(baseURL, ZIP, key)
await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
await updateUI()
}

your postData() is also an async function. Therefore you have to await this aswell:
getWeather(baseURL, ZIP, key,).then(async (data) => {
await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings })
}).then(
updateUI()
)}
I didn't have done javascript in a while, but i guess it is more clear in this way:
const performAction = async (e) => {
const ZIP = document.getElementById('zip').value;
const fellings = document.getElementById('feelings').value;
console.log(`${baseURL}${ZIP},us&appid=${key}`);
try{
const data = await getWeather(baseURL, ZIP, key,);
const postData= await postData('/addweather', {temperature: data.main.temp ,date:newDate, userResponse: fellings });
} catch(e) {
console.log(e)
} finally {
updateUI();
}
Also you dont have to await the parsing of the json and the try catch should contain your request:
const postData = async ( url = '', data = {}) => {
console.log(`This is what we fetch ${data.temperature}`);
console.log(`This is what we fetch ${data.date}`);
console.log(`This is what we fetch ${data.userResponse}`);
try {
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
// Body data type must match "Content-Type" header
body: JSON.stringify(data),
});
const newData = response.json();
console.log(`This is the new Data ${newData.temperature}`);
return newData;
}catch(error){
console.log("error", error);
}}

Related

Can't get the proper object back

Hi i'm using MeaningCloud's api to get the proper object back once it analyses a string of text or a url for the Natural language processing (NLP). But it doesn't return the proper object.
Right now the code returns a string with the text "[Object object]" on the HTML page. I need it to return the results of the api call which returns the proper JSON object(that I can see in the console) in a proper "key/value" pair format on the HTML page.
Here's my script:
const baseURL = "https://api.meaningcloud.com/sentiment-2.1";
const key = "Your_api_key";
const submitBtn = document.getElementById("submitBtn");
submitBtn.addEventListener("click", (e) => {
e.preventDefault();
const url = document.getElementById("url").value;
if (url !== "") {
getData(baseURL, url, key)
.then(function (data) {
postData("/add", { data: data });
}).then(function () {
receiveData()
}).catch(function (error) {
console.log(error);
alert("Invalid input");
})
}
})
const getData = async (baseURL, url, key) => {
const res = await fetch(`${baseURL}?key=${key}&txt=${url}`)
try {
const data = await res.json();
return data;
}
catch (error) {
console.log("error", error);
}
}
const postData = async (url = "", data = {}) => {
const response = await fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
data: data
})
});
try {
const newData = await response.json();
return newData;
} catch (error) {
console.log(error);
}
};
const receiveData = async () => {
const request = await fetch('/all');
try {
// Transform into JSON
const allData = await request.json()
console.log(allData)
// Write updated data to DOM elements
document.getElementById('result').innerHTML = allData;
}
catch (error) {
console.log("error", error);
// appropriately handle the error
}
}
I have another main file that's the server.js file which I run using node server.js that renders the html page properly but the script doesn't render the results on the page properly. You can signup on meaningcloud for a free api key that has a very convenient number of calls you can make.

React Native - Variable does not update correctly when retrieving data from AsyncStorage

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);
}
});

Mutiple Axios return not able to return the value but in cosole it is coming

Multiple Axios return not able to return the value but in console it is coming
first function is able to return the data>
second and 3rd is not able to do>
< the first function is able to return the data>
<the second and 3rd is not able to do>
async getdata() {
let url = `xxxxxxxx`;
this.axiosConfig = {
withCredentials: false,
maxRedirects: 3
};
let config: AxiosRequestConfig = { ...this.axiosConfig
};
//axios.defaults.headers.common = { 'Authorization': 'Bearer ' + this.token }
var result = await axios.get(url, config);
console.log(result.data); // --------------> data is coming here
return result.data; //------------>able to return the data from here
}
async getfame() {
var res = await this.getdata()
res.map(async(item: any) => {
let url = `xxxxxxxx`;
this.axiosConfig = {
withCredentials: false,
maxRedirects: 3
};
let config: AxiosRequestConfig = { ...this.axiosConfig
};
//axios.defaults.headers.common = { 'Authorization': 'Bearer ' + this.token }
var result1 = await axios.get(url, config);
console.log(result1.data); // -----------------> data coming here
return result1.data; //------------> not able to return the data from here
//return axios.get<string>(url, config);
})
}
async getfix() {
var res1 = await this.getdata()
res1.map(async(item: any) => {
let url = `xxxxxxxx`;
this.axiosConfig = {
withCredentials: false,
maxRedirects: 3
};
let config: AxiosRequestConfig = { ...this.axiosConfig
};
//axios.defaults.headers.common = { 'Authorization': 'Bearer ' + this.token }
var result2 = await axios.get(url, config);
console.log(result2.data); // -----------------> data coming here
return result2.data; //------------> not able to return the data from here
//return axios.get<string>(url, config); //-------------> tried this way but still not coming
})
}
In your second and third functions, you're returning those axios calls inside an array map. The outer function is not returning anything.
If you add a return before each .map() call, then the functions will return an array of your expected results.
async getfame() {
var res = await this.getdata()
return res.map(async(item: any) => {
/* ... */
return result1.data;
})
}
async getfix() {
var res1 = await this.getdata()
return res1.map(async(item: any) => {
/* ... */
return result2.data;
})
}

How can I send fcmtoken to the api body?

When useEffect is executed in my code, I want to get fcmtoken through firebase .getToken and send fcmtoken to body of auth/me router.
but if i use my code this error occure
Unhandled Promise Rejection (id: 0):
ReferenceError: fcmtoken is not defined
Perhaps the cause of the error is incorrect use of async await or anything
but how can i fix my code?
this is my code
useEffect(() => {
Linking.addEventListener('url', async ({url}) => {
var newURL = url;
var splitURL = newURL.toString().split('=');
const token = splitURL[1];
messaging()
.getToken()
.then((fcmtoken) => {
return fcmtoken;
});
const {data} = await axios.post(
'/auth/me',
{fcmtoken},
{
headers: {Authorization: `Bearer ${token}`},
},
);
console.log('data::::', data);
AsyncStorage.setItem('tokenstore', `${token}`, () => {
console.log('유저 닉네임 저장 완료');
});
dispatch({
type: KAKAOLOG_IN_REQUEST,
data: data,
});
});
return () => Linking.removeEventListener('url');
}, []);
you are trying to send an undefined variable 'fcmtoken' to the API. In the code bellow I changed the way you get the fcm token.
useEffect(() => {
Linking.addEventListene`enter code here`r('url', async ({url}) => {
var newURL = url;
var splitURL = newURL.toString().split('=');
const token = splitURL[1];
let fcmtoken = await messaging().getToken();
const {data} = await axios.post(
'/auth/me',
{fcmtoken},
{
headers: {Authorization: `Bearer ${token}`},
},
);
console.log('data::::', data);
AsyncStorage.setItem('tokenstore', `${token}`, () => {
console.log('유저 닉네임 저장 완료');
});
dispatch({
type: KAKAOLOG_IN_REQUEST,
data: data,
});
});
return () => Linking.removeEventListener('url');
}, []);

array to objects in a react.js form

I have a form code that the api is a PUT method, I have a part where I have to send it in the form of a objects, but when I send it it sends it to me as an array, they also tell me that I have to send them if it is true or false
handleSubmit = async (event) => {
const {
state,
city,
mild_symptoms = [],
} = event
const YES = "Si"
console.log(event)
try {
const myHeaders = new Headers();
const url =
"XXXXXXXXX";
myHeaders.append(
"x-api-key",
"XXXXX"
);
myHeaders.append("state", state);
myHeaders.append("city", city);
myHeaders.append(
"mild_symptoms",
`{"flu_syndrome": ${mild_symptoms.includes("flu_syndrome")}, "conjunctivitis": ${mild_symptoms.includes("conjunctivitis")}, "muscle_pain": ${mild_symptoms.includes("muscle_pain")}}`
);
var requestOptions = {
method: "PUT",
headers: myHeaders,
mode: "cors"
};
const response = await fetch(url, requestOptions);
console.log("FIRST RESPONSE ", response);
const result = await response.text();
console.log("RESULT", result);
Modal.success({
title: "Éxito",
content: "Datos enviados correctamente",
onOk: ()=>{
window.location.href = "https://covid19.gob.sv/orientaciones-tecnicas/"
}
})
} catch (error) {
console.log("ERROR", error);
}
I have to send this as a objects and not as an array
"mild_symptoms",
`{"flu_syndrome": ${mild_symptoms.includes("flu_syndrome")}, "conjunctivitis": ${mild_symptoms.includes("conjunctivitis")}, "muscle_pain": ${mild_symptoms.includes("muscle_pain")}}`
);

Categories