How to test useEffect with Auth api and state inside - reactjs

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

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

No function is getting called inside firebase get function

I am trying to write login code, but this firebase get function is refraining me to do so. I am unable to call any function (except alert), within this get function. Navigating to another component also does not work here. I know I have to use async/await keywords but I dont know how to. Can someone please help me with this?
Pasting the code below.
navigate() {
alert("Aya");
}
login() {
const { uname } = this.state;
const { password } = this.state;
var userid = "";
var data;
if (uname && password) {
firebase
.auth()
.signInWithEmailAndPassword(uname, password)
.then(async user => {
userid = await firebase.auth().currentUser.uid;
await db.collection("Users").doc(userid)
.get()
.then(function (doc) {
if (doc.exists) {
data = doc.data();
alert(JSON.stringify(data.role));
if (data.role === "Company Admin") {
logged = true;
alert("Yahoo");
this.navigate();
}
else {
logged = false;
}
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function (error) {
console.log("Error getting document:", error);
});
})
.catch(error => {
alert(error);
this.setState({ error });
});
if (logged) {
alert(logged);
}
else {
alert("Nope");
}
}
else {
alert("Enter all fields data");
}
}
Don't use normal function, you are going to lose the context of this. The this in the callback function is not pointing to your class. So this.navigate() line of code won't work
.then(function (doc) {
As a solution, Use arrow function.
...
.then((doc) => {
...

UseEffect not returning response onMount

I am running a test on page load and refresh. It is working well but the test is returning 0;
below is my code;
useEffect(() => {
setLoading(true);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(getPosition);
} else {
setError("Your browser doesn't support geolocation");
}
const fetchLocations = async () => {
if(currentPos.latitude!==undefined && currentPos.longitude!==undefined) {
try {
const response = await instance
.get("/explore", {
params: {
ll: `${currentPos.latitude},${currentPos.longitude}`
}
})
console.log(response.data.response.groups[0].items);
setLocations(response.data.response.groups[0].items);
setError('')
setLoading(false)
} catch (error) {
setError('Error getting data');
setLoading(false)
}
}
}
fetchLocations()
}, [currentPos.latitude, currentPos.longitude]);
and my test:
What is happening here is on first mount loading... is available. On fetching data from the API is expected toHaveBeenCalledTimes to be 1 instead of returning 0.
it("renders location venues on currentlocation ", async () => {
const {getByText, container} = render(<Venues />);
getByText('Loading...')
await axiosMock.get.mockResolvedValueOnce(() =>
Promise.resolve({ data: {response } })
)
expect(axiosMock.get).toHaveBeenCalledTimes(0)
await waitForElement(() =>
container,
expect(axiosMock.get).toHaveBeenCalledTimes(1)
);
});
How can I fix this test and make it work properly?

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

Resources