react setstate not rerenering - reactjs

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

Related

How to test useEffect with Auth api and state inside

useEffect(()=>{
Auth.currentAuthenticatedUser().then((user) => {
setUser(user)
setIsLoading(false)
if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {
navigate('/ForceChangePassword')
}
else{
navigate('/App')
}
}).catch(error => {
console.log('isCurrentAuthenticatedUser- ',error)
setUser(null)
setIsLoading(false)
})
});
We can simply mock the Auth.currentAuthenticatedUser() part.
For example:-
Auth.currentAuthenticatedUser = jest.fn().mockImplementation(()=>Promise.resolve({challengeName: 'NEW_PASSWORD_REQUIRED'}))
If someone wants to cover the catch block then:-
Auth.currentAuthenticatedUser = jest.fn().mockImplementation(()=>Promise.reject())

Not run after await

After the first await the code stops running this is my code:
handleSubmit = async e => {
e.preventDefault();
const { name, number, email, message } = this.state;
try {
await axios.post("http://localhost:3001/send", {
name,
number,
email,
message
});
} catch (ex) {
this.setState({ result: "There was an error, try again." });
}
try {
const response = await fetch("http://localhost:3001/result");
const data = await response.json();
this.setState({ result: data });
} catch (ex) {
this.setState({ result: "There was an error, try again." });
}
};
but the second await in the second try doesn't work.
Can someone help me
You're mixing two different concepts here - async/await and promise chaining. If you want to go with async/await, try something like this.
try {
let response = await fetch("http://localhost:3001/result");
let data = await response.json();
this.setState({ result: data });
} catch (ex) {
this.setState({ result: "There was an error, try again." });
}
I found the solution in my node code i put res at the same url (.../send) and it works

Axios promise will never resolve

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

await aborts the function in a React app. why?

I am trying to fetch data and set the state in React App. While the fetch is successful, as I can see the data in chrome dev tools, the execution stops at await statement in the below code. Only "getting data" is logged. Looks like after fetch statement the function returns, with all the following steps running successfully.
What am I doing wrong??
Any kind of help is much appreciated.
import util from "util";
const fetchProm = util.promisify(fetch)
....
getDataFromDb = async () => {
console.log('getting data')
let result = await fetchProm("http://localhost:3001/getData")
.then(data => {
console.log("then1:",data)
return data.json()
})
.then(res => {
console.log('then2:', res.data)
return { data: res.data }
})
.catch(err => {
return { err: err.data }
});
console.log("result:", result)
this.setState({ data: result.data })
};
you do not need .then callback if you use async-await.
try below sample :
import util from "util";
const fetchProm = util.promisify(fetch)
getDataFromDb = async () => {
console.log('getting data')
let {data} = await fetchProm("http://localhost:3001/getData");
console.log("result:", data)
this.setState({ data })
};
With async/wait you don't need the then. Also you catch errors on the second then and not the first.
Can you try:
let result = await fetchProm("http://localhost:3001/getData")
console.log(result)
and see if it works?
When using async/await, don't forget to handle your exceptions with try/catch
Change your code to:
import util from "util";
getDataFromDb = async () => {
try{
let {data} = await fetchProm("http://localhost:3001/getData");
this.setState({ data })
}
catch(err=> this.setState({ err: err.data }))
};

AsyncStorage.getItem in react native not working as expected

I am trying to fetch data using AsyncStorage. whenever i call my action creator requestData and do console on the data which is passed , i get something like below .I have two version of getItem .In both the version i get useless value for property field . Property value should be readable
{"fromDate":"20160601","toDate":"20160701","property":{"_40":0,"_65":0,"_55":null,"_72":null},"url":"/abc/abc/xyz"}
async getItem(item) {
let response = await AsyncStorage.getItem(item);
let responseJson = await JSON.stringify(response);
return responseJson;
}
async getItem(item) {
try {
const value = AsyncStorage.getItem(item).then((value) => { console.log("inside componentWillMount method call and value is "+value);
this.setState({'assetIdList': value});
}).then(res => {
return res;
});
console.log("----------------------------value--------------------------------------"+value);
return value;
} catch (error) {
// Handle errors here
console.log("error is "+error);
}
}
componentWillMount() {
requestData({
fromDate: '20160601',
toDate: '20160701',
assetId: this.getItem(cmn.settings.property),
url: '/abc/abc/xyz'
});
}
You are getting property as a promise, you need to resolve it.
Try to use something link that.
assetId: this.getItem(cmn.settings.property).then((res) => res)
.catch((error) => null);
Since AsyncStorage is asynchronous in nature you'll have to wait for it to return the object AND THEN call your requestData method; something like the following -
class MyComponent extends React.Component {
componentWillMount() {
this.retrieveFromStorageAndRequestData();
}
async getItem(item) {
let response = await AsyncStorage.getItem(item);
// don't need await here since JSON.stringify is synchronous
let responseJson = JSON.stringify(response);
return responseJson;
}
async retrieveFromStorageAndRequestData = () => {
let assetId = await getItem(cmn.settings.property);
requestData({
fromDate: '20160601',
toDate: '20160701',
assetId,
url: '/abc/abc/xyz'
}) ;
}
// rest of the component
render() {
// render logic
}
}

Resources