Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialKilleon Patterson
18,528 PointsHow do l detect a user attempting to leave a page/close a tab/back button?
I'm attempting to alert a user from leaving the page, closing a tab, or returning to a previous window during a stripe card purchase process. How do I manage the payments so a user's behavior doesn't interrupt the intended flow if they. Thank you.
//lines 112-129 are where I tried detecting window loadings.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import CardSection from './CardSection.component';
import Modal from './modal.component';
import {injectStripe} from 'react-stripe-elements';
const CheckoutForm = props => {
const [name, setName] = useState("");
const [mentionMan, setMentionMan] = useState("");
const [commId, setCommId] = useState("");
const [confirm, setConfirmMe] = useState(false);
const [nono, setNono] = useState(["StripeCardError"]);
const [openModal, setOpenModal] = useState(false);
let barneyId = null;
const confirmed = () => {
const answer = {
commId: barneyId,
ready: "order received!"
}
axios.post('http://localhost:5000/users/confirmed', answer, { headers:
{
"this-token": localStorage.getItem("this-token")
}
})
.then(res => {
setOpenModal(false);
deleteOrder();
})
.catch((error) => {
console.log(error);
})
}
const receiptMe = async () => {
barneyId = Math.floor(Math.random() * 1001);
const receipter = {
yourOrder: props.adCart,
amounter: props.amount,
commId: barneyId
}
console.log(barneyId);
await axios.post('http://localhost:5000/users/receiptme/', receipter, { headers:
{
"this-token": localStorage.getItem("this-token")
}
})
.then(res => console.log("You tried it..."));
}
const postOrder = async () => {
const info = {
adCart: props.adCart,
commId: barneyId
}
await axios.post('http://localhost:5000/users/orders/info', info, { headers:
{
"this-token": localStorage.getItem("this-token")
}
})
.then(res => {
console.log(info);
})
.catch((error) => {
console.log(error);
})
}
const deleteOrder = () => {
axios.delete('http://localhost:5000/users/orders/all', { headers:
{
"this-token": localStorage.getItem("this-token")
}
})
.then(response => {
console.log("ok");
window.location = "/status";
})
.catch((error) => {
console.log(error);
})
}
const handleInputChange = (event) => {
setName(event.target.value);
}
const boxStuff = () => {
console.log("Man");
}
const lockBox = () => {
console.log("Wally");
}
const handleSubmit = async (ev) => {
// prevent event
// prevent event
ev.preventDefault();
//Attempting to detect a user leaving
if (ev.target) {
window.addEventListener("beforeunload", boxStuff(), {capture: true});
} else {
window.removeEventListener("beforeunload", lockBox(), {capture: true});
}
try {
let {
token: { id },
} = await props.stripe.createToken({ name: name });
let amount = props.amount;
setOpenModal(true);
let res = await axios.post(
'http://localhost:5000/users/pay',
{
token: id,
amount,
},
{
headers: {
'this-token': localStorage.getItem('this-token'),
},
},
);
console.log(res.data);
let eMan = nono.filter((el) => el === res.data);
await (eMan.length > 0) ? console.log("Card did not go through.") : receiptMe();
if (eMan.length > 0) {
setMentionMan('There was an error with your card.');
} else {
postOrder();
confirmed();
}
} catch (error) {
console.log(error);
}
}
return (
<div>
<input
type="string"
value={name}
name="name"
placeholder=" Card Name"
onChange={handleInputChange}
style={{
border: "1px",
borderTopStyle: "hidden",
borderRightStyle: "hidden",
borderLeftStyle:"hidden",
borderBottomStyle: "groove",
borderColor: "black",
marginBottom: "2%"}} />
<form onSubmit={handleSubmit}>
<CardSection/>
<button type="submit" value="Submit" className="btn btn-outline-primary" >
Confirm order
</button>
</form>
<h3>
Total Amount:
</h3>
<p>
${props.amount}
</p>
<p>{mentionMan}</p>
{openModal && <Modal closeModal={setOpenModal} />}
</div>
);
}
export default injectStripe(CheckoutForm);
2 Answers
Rohald van Merode
Treehouse StaffHey Killeon Patterson,
I'd suggest to checkout the Promp component that comes with React Router. This enables you to get that functionality without to much additional code.
If you're using React Router v6 it's a hook called usePrompt
of which you can find a nice example here
Hope this helps 🙂
Steven Parker
231,275 PointsThe event handler should accept the event object as a parameter and include event.preventDefault();
to stop the default action (closing). Be aware that as a security measure, browsers typically will only display their own warning message, and even this might not happen if no other user interaction has occurred since the window or tab opened.
Killeon Patterson
18,528 PointsThank you for your reply, Steven.
"ev" is the event parameter referenced. "ev.preventDefault()" along with "ev.target" are being used inside the handleSubmit function. When I submit the payment, I'm still able to close the window/return/navigate to another page. I tested changing the references specifically to "event" and it appears to have the same results.
Steven Parker
231,275 PointsThe event handlers "boxStuff" and "ockBox" don't currently accept arguments or call preventDefault.
Also, when establishing the listener, only name the handler and don't call it.
Killeon Patterson
18,528 Points- Steven Thank you for your reply. I got it working.
Killeon Patterson
18,528 PointsKilleon Patterson
18,528 PointsHello Rohald van Merode
It did help. Thank you for your response : )