Axios promise will never resolve - reactjs

For the life of me, I can never get my Axios.post promise to resolve.
I know that my front end and backend are perfectly connected.
Try/catch blocks to return the resolved promise haven't worked either.
No matter what I do, I can never get inside of my promise.then() function. What am I doing incorrectly in my backend file?
CODE THAT HASN'T WORKED TO RESOLVE THE PROMISE
async handleDateSubmit() {
let resolvedPromise = await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
resolvedPromise
.then(response => {
//I can never get to here.
console.log("Made it inside");
})
.catch(err => console.log(err));
}
//---attempt two----//
async getResolvedPromise() {
try {
return await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
} catch (error) {
console.log(error);
}
}
async handleDateSubmit() {
let resolvedPromise = this.getResolvedPromise();
//work with resolvedPromsie
}
CURRENT CODE
//------------send_info.js front end file----------//
handleDateSubmit() {
Axios.post('http://localhost:3001/get_number_of_dates_from_email', {
email: this.state.user_email_m
})
.then((response) => {
//I can never get to here.
console.log("Made it inside");
})
.catch(err => console.log(err));
}
//---------------server.js backend file---------------//
router.route('/get_number_of_dates_from_email').post(function (req, res) {
//"user_email" is correct in my schema model and "req.body.email" is always what it should be
User.findOne({ user_email: req.body.email }, (err, foundUser) => {
console.log("Inside of findOne()");
if (err) {
return res.send(err);
}
else {
let numDates = foundUser.dates_list.length;
//I always get here and numDates is always correct
console.log("Number of dates: ", numDates);
return res.json({ "numDates": numDates }); //Should I be using res.send()?
}
});
});

It seems like you're confusing promises and resolved promises at times in your code
// Attempt one
async handleDateSubmit() {
try {
let resolvedPromise = await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
// Here resolvedPromise as stated by its name is not a promise anymore, thus you can't use .then()
// You can directly work with resolvedPromise as it contains the response.
} catch (e) {
console.error(e)
}
}
// Attempt two
async getResolvedPromise() {
try {
// Here you're returning the resolved promise, but the async await syntax turn your function into an AsyncFunction object
// This type of function will wrap the return value in a promise if it's not one
return await Axios.post(
"http://localhost:3001/get_number_of_dates_from_email",
{
email: this.state.user_email_m
}
);
} catch (error) {
console.log(error);
}
}
async handleDateSubmit() {
// Thus you need to await the result of your function
let resolvedPromise = await this.getResolvedPromise();
}

Related

How to make a PATCH request in ReactJS ? (with Nestjs)

nestjs controller.ts
#Patch(':id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
#Body('shippingAddr') addrShipping: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling, addrShipping);
return null;
}
nestjs service.ts
async updateProduct(
addressId: string,
addrBilling: boolean,
addrShipping: boolean,
) {
const updatedProduct = await this.findAddress(addressId);
if (addrBilling) {
updatedProduct.billingAddr = addrBilling;
}
if (addrShipping) {
updatedProduct.shippingAddr = addrShipping;
}
updatedProduct.save();
}
there is no problem here. I can patch in localhost:8000/address/addressid in postman and change billingAddr to true or false.the backend is working properly.
how can i call react with axios?
page.js
const ChangeBillingAddress = async (param,param2) => {
try {
await authService.setBilling(param,param2).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
return....
<Button size='sm' variant={data.billingAddr === true ? ("outline-secondary") : ("info")} onClick={() => ChangeBillingAddress (data._id,data.billingAddr)}>
auth.service.js
const setBilling = async (param,param2) => {
let adressid = `${param}`;
const url = `http://localhost:8001/address/`+ adressid ;
return axios.patch(url,param, param2).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}
I have to make sure the parameters are the billlingddress field and change it to true.
I can't make any changes when react button click
Since patch method is working fine in postman, and server is also working fine, here's a tip for frontend debugging
Hard code url id and replace param with hard coded values too:
const setBilling = async (param,param2) => {
// let adressid = `${param}`;
const url = `http://localhost:8001/address/123`; // hard code a addressid
return axios.patch(url,param, param2).then((response) => { // hard code params too
console.log(response); // see console result
if (response.data.token) {
// localStorage.setItem("user", JSON.stringify(response.data));
}
// return response.data;
})
}
now it worked correctly
#Patch('/:id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling);
return null;
}
const ChangeBillingAddress = async (param) => {
try {
await authService.setBilling(param,true).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
const setBilling= async (param,param2) => {
let id = `${param}`;
const url = `http://localhost:8001/address/`+ id;
return axios.patch(url,{billingAddr: param2}).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}

Clearing an item from AsyncStorage - React native

I'm new to react native currently i'm working on a project that needs to update a specific value in async storage. I tried by clearing an item from Asyncstorage using this code await AsyncStorage.removeItem(key); but when i used it console throws an error like this 'await' is only allowed within async functions . But i'm using an async function
const getExceedCountData = async () => {
const token = await AsyncStorage.getItem("#userToken")
const exceedcount = await AsyncStorage.getItem("#exceedCount")
if(!exceedcount){
try {
setLoading(true)
axios
.get(constants.BASE_URL + "getexceedcount?token=" +token)
.then(response => {
if(response.data.status == 1){
try {
await AsyncStorage.removeItem("#exceedCount");
}
catch(exception) {
console.log('Error Occured');
}
AsyncStorage.setItem("#exceedCount", response.data.result);
setExceedCount({ value:response.data.result, error: '' })
}
})
.catch(error => {
console.log(error);
});
} catch(error) {
console.log(error);
}
}else{
setExceedCount({ value:exceedcount, error: '' })
}
}
I don't know why this issue occured. Any help is appreciable.
You need to notate the function as async.
.then(async (response) => {
if(response.data.status == 1){
try {
await AsyncStorage.removeItem("#exceedCount");
}
catch(exception) {
console.log('Error Occured');
}
AsyncStorage.setItem("#exceedCount", response.data.result);
setExceedCount({ value:response.data.result, error: '' })
}
})
The scope of the function inside .then is not declared as async. This should fix your problem:
.then(async response => {
if(response.data.status == 1){
try {
await AsyncStorage.removeItem("#exceedCount");
} catch(exception) {
console.log('Error Occured');
}
AsyncStorage.setItem("#exceedCount", response.data.result);
setExceedCount({ value:response.data.result, error: '' })
}
})

Why is res.json returning empty?

When I make a "GET" request from the client to the server the server should make a axios.get() call to a stock API to retrieve data for an array of tickers. When I console.log the results it seems to be working fine but the array doesn't seem to save, like it gets wiped out and comes back to the client as empty. I think I might be messing this up with async/await.
async function currentPrice(ticker) {
const apiURL = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${ticker}&apikey=${API_KEY}`;
let price;
await axios.get(apiURL).then(data => {
try {
price = data.data["Global Quote"]["05. price"];
} catch (error) {
console.log(error)
}
})
return price;
};
app.get("/refresh", redirectLogin, (req, res) => {
const {
user
} = res.locals;
var array = [];
connection.query(`SELECT * FROM holdings WHERE user_name = '${user.user_name}' AND quantity > 0`, (err, results) => {
if (err) throw err;
results.forEach(holding => {
currentPrice(holding.ticker).then(data => {
var updatedTicker = {
ticker: holding.ticker,
description: holding.description,
price_acquired: holding.price_acquired,
market_price: data,
delta: parseFloat(this.market_price) - parseFloat(this.price_acquired),
quantity: holding.quantity,
trade_date: holding.date_acquired
}
array.push(updatedTicker);
// console.log(array);
console.log(updatedTicker.market_price)
})
})
res.json(array)
})
})
You are calling res.json(array) before any of your currentPrice().then(...) calls have finished, thus the array is still empty.
There are a number of different ways to solve this. Probably the simplest is to change for .forEach() loop to a plain for loop and then use async/await to serialize each of your calls to currentPrice():
function currentPrice(ticker) {
const apiURL = `https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=${ticker}&apikey=${API_KEY}`;
return axios.get(apiURL).then(data => {
try {
return data.data["Global Quote"]["05. price"];
}
catch (error) {
console.log(error);
throw error;
}
});
}
app.get("/refresh", redirectLogin, (req, res) => {
const { user } = res.locals;
connection.query(`SELECT * FROM holdings WHERE user_name = '${user.user_name}' AND quantity > 0`, async (err, results) => {
if (err) {
console.log(err);
res.sendStatus(500);
return;
}
try {
const array = [];
for (let holding of results) {
let data = await currentPrice(holding.ticker);
let updatedTicker = {
ticker: holding.ticker,
description: holding.description,
price_acquired: holding.price_acquired,
market_price: data,
delta: parseFloat(this.market_price) - parseFloat(this.price_acquired),
quantity: holding.quantity,
trade_date: holding.date_acquired
}
array.push(updatedTicker);
}
res.json(array);
} catch(e) {
console.log(e);
res.sendStatus(500);
}
});
});
Various changes:
Simplified the currentPrice() function to just return the axios promise directly
Appropriately reject in currentPrice() if there's an error so the caller sees the error.
Add proper error handling (sending an error response), if the db query fails.
Switch .forEach() loop to a for loop so we can use await to serialize the calls to currentPrice() so we can more easily know when they are all done.
Add error handling and sending of an error response if currentPrice() has an error.
Call res.json(array) only after all the now-serialized calls to await currentPrice() have completed.
FYI, a fully complete transformation here would switch to mysql2 so you can use the promise interface for connection.query() rather than the plain callback interface that you are using now. That would allow you to consolidate error handling to one place more easily.

react setstate not rerenering

I have the following:
onTransfer = async () => {
this.setState({loading: true});
try {
const accounts = await web3.eth.getAccounts();
await this.props.myData.methods.transferBalanceToOwner().send({
from: accounts[0]
});
let contractBalance;
await web3.eth.getBalance(this.props.address).then(function(result) {
contractBalance = web3.utils.fromWei(result);
});
console.log('contract balance: ', contractBalance);
this.setState({ contractBalance });
} catch (error) {
console.log('Transfer to owner error: ',error)
}
this.setState({loading: false});
}
and I have the following in my render()
if (this.state.isOwner) {
ownerUI = (
<Container>
<Divider/>
<p>Contract balance: {this.state.contractBalance}</p>
<Button loading={this.state.loading} onClick={this.onTransfer} primary>Transfer Balance</Button>
</Container>
)
}
For some reason, the contract balance is not getting update after OnTransfer. Can someone spot what I might be doing wrong?
Thanks!
Its not right way to use async/await.
With async/await there is no thenable
Put await statement inside try/catch block for success/error check.
The correct way to do this.
let contractBalance;
try {
//success check
contractBalance = await web3.eth.getBalance(this.props.address)
this.setState({contractBalance});
}
catch (rejectedValue) {
//error check
console.log(rejectedValue)
}

Persisting data if none exists for a certain key using AsyncStorage

I'm trying to set up a function where I first check to see if I have a value for a certain key, and if I do not, I use the axios library to get a value from the web and persist it as that key's value instead. Here is my code:
async getName() {
try {
const value = await AsyncStorage.getItem('dummy'); //the value should be a JSON object
if (value !== null){
return value.name;
}
else {
axios.get('https://api.github.com/users/dummy')
.then(function (response) {
console.log(response);
try {
await AsyncStorage.setItem('dummy', 'dummyval');
} catch (error) {
console.log(error);
}
return(response.name);
})
.catch(function (error) {
console.log('Error fetching name: ' + error.response);
});
}
} catch (error) {
console.log(error);
}
I'm pretty new to React Native, so I'm sure this looks like a mess. I know I must be doing something wrong because I keep getting a syntax error on the second use of await. Does anyone know how to properly structure these calls?
You need to declare axios's success handler using async keyword. In your code, you have written like .then(function (response), this should be changed to .then(async function (response).
Consider following changes.
async getName() {
try {
const value = await AsyncStorage.getItem('dummy'); //the value should be a JSON object
if (value !== null){
return value.name;
}
else {
axios.get('https://api.github.com/users/dummy')
.then(async function (response) {
console.log(response);
try {
await AsyncStorage.setItem('dummy', 'dummyval');
} catch (error) {
console.log(error);
}
return(response.name);
})
.catch(function (error) {
console.log('Error fetching name: ' + error.response);
});
}
} catch (error) {
console.log(error);
}
}
Hope this helps!

Resources