how to run firebase update once? - javascript

I have a button and when we press it, Firebase updates some value in Firebase. How can I control users? When we press it, Firebase updates some value in Firebase. How can I control users' presses? And allow the user to press this button only once?
My idea is that when opening some page in useEffect, I check if this user pressed a button earlier (I store all users' IDs to check if a user pressed a button) and if there is no user ID, then I allow the user to press the button, but if there is a user ID, then I disable the button and the user can't press it again.
But here is some problems. When user open page while firebase checks if there is user button is available for pressing. This is problem and I dont' want to allow do that.
And also if previosly user didn't press the button and now wants to do that then I need to imidiatelly disable it to prevent pressing it more than once.
How To disable button while data is fetched from firebase (on page loading)
How To disable button after 'click'

Here's a test component which accomplishes what you are asking:
import React, {useEffect, useState} from 'react';
import { Button } from 'react-native-paper';
const Test = props => {
const [isButtonDisabled, setIsButtonDisabled] = useState(false);
useEffect(() => {
const fetchMyAPI = async () => {
setIsButtonDisabled(true) // Disable button
let response = await fetch('api/data')
response = await response.json()
// Do whatever you want with response
setIsButtonDisabled(false) // Enable button after fetching
}
fetchMyAPI()
}, [])
const onPressHandler = () => {
setIsButtonDisabled(true)
// Button functionality can go here
}
return (
<Button onPress={onPressHandler} disabled={isButtonDisabled}></Button>
);
};
export default Test;
This is for react native so just replace the react native Button with whatever button you want to use.
Edit:
If you are having a problem with the button disabled state when reloading this component it is likely due to the component re-rendering. You will have to lift the state up to the parent and pass the state back down to the children. This will avoid the state being reset when the button gets re-rendered.
See the react docs https://reactjs.org/docs/lifting-state-up.html

Related

Close a modal when user clicks back button in browser React Js

I am showing user a modal that takes over the entire screen if user is accessing the website on phone. A user tends to instinctively click the back button on their phone to go back to the previous screen instead of using the close button provided on the modal.
Is there a way to intercept the function that is triggered when a user clicks the back button? I want to close the modal when user clicks the back button on their phone, instead of having them redirect to the previous page.
Use the History API. An example on how to acomplish this is:
//listen for state changes
window.onpopstate = (event) =>
{
if (!event.state.modalOpened)
{
closeModal()
}
}
//change the actual page state so it contains the modalOpened property
window.history.replaceState({modalOpened: false})
function openModal(content)
{
//push new state, put the modal information in the state object, this will push a new state, when the user presses the back button, the browser will just trigger the onpopstate event, instead of going to the previous page
window.history.replaceState({modalOpened: true})
//this is any code you use to open your modal, for example
ReactDOM.render(<Modal>{content}</Modal>, document.getElementById("modal-container")
}
class based component
There are many ways to aproach this, this is one of them, everything you need to make something that fits with your app is in the History API DOCS.
//listen for state changes
window.onpopstate = (event) =>
{
if (!event.state.modalOpened)
{
updateModal(false, null)
}
}
function openModal()
{
//push new state, put the modal information in the state object, this will push a new state, when the user presses the back button, the browser will just trigger the onpopstate event, instead of going to the previous page
window.history.replaceState({modalOpened: true})
updateModal(false, <div>Modal content!</div>)
}
function updateModal(open, content)
{
ReactDOM.render(<Modal open={open} content={content} />, document.getElementById("modal-container")
}
//change the actual page state so it contains the modalOpened property
window.history.replaceState({modalOpened: false})
class Modal extends React.Component {
constructor(props) {
super(props);
}
render() {
//check the history to determine if we have to open or close the modal
return <div className={"modal " + (props.open)? "show" : ""}><div className="modal-content">{props.content}</div><button onClick={() => window.history.back()}>OK</button></div>;
}
}

track form changes when user leaving page/refreshing

I have a form which is written using formik and react-hooks. I am trying get recommendations on how to track a form change when user clicks home button or page refresh/reload?
I have tried, browser history method to trigger a modal to show unsaved changes
const unlisten = browserHistory.listen( location => {
//trigger modal here
});
But this seems to doesn't work. Also I am using react-router...if any suggestions using that will be helpful.
I am all done storing formvalues into a state using useState and setState,
I have a modal to show when exit button is clicked on form to track form changes but I am not sure how to detect outside of form.
I will put this here as a posible workaround to the question.
When you update your form in your handleChange method (whatever it is),you can also update user localstorage. With this approach you can check when page loads if there is some values in storage from older sessions or before.
Setting Values:
this.setState({ item1: value }, () => {
localStorage.setItem('myForm', JSON.stringify(this.state));
});
Getting values:
componentDidMount() {
const storedValues = JSON.parse(localStorage.getItem('myForm'))
this.setState({...storedValues});
}
Restore Data:
In your onSubmit method remember to clear localStorage
localStorage.removeItem('myForm');
I'm using react-router-navigation-prompt for exactly that purpose, it's made for react router. Just add this component inside your <Form/> / <form/>,
<NavigationPrompt
when={formProps.dirty}>
{({ isActive, onConfirm, onCancel }) => {
if (isActive) {
return (
<ConfirmationPopUp
isOpen
onConfirm={onConfirm}
onCancel={onCancel}
/>
);
}
}}
</NavigationPrompt>

Custom Modal Dialog Box in Browser back in Angular 4+

Suppose my current route is /transact/orders and is in Order summary view, What I want to do is to open a custom dialog which gives the option to add to cart or cancel button when he/she presses browser back button of the browser.If user press add to cart button it goes to the cart or else the browser back button functionality will happen. Currently, I am using Angular 5.2.I would like to know if it is possible with LocationStrategy.I searched but could not get a proper example of it.Can anybody explain with proper example?
You can subscribe to Location events anywhere you want to do actions on back button pressed:
import { Subscription } from 'rxjs/Subscription';
ngOnInit() {
this.subscription = <Subscription> this.location.subscribe( () => {
// your code here
} );
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
Don't forget to unsubscribe in OnDestroy.
EDIT: location should be type Location, not LocationStrategy

Prevent component from unmounting - showing notification to users before opening other component

In my web app there is a form where users put in data. If they want to navigate to other component or back, I want to notify them that changes were made to form and show them confirmation dialog.
I know how to implement this if users click on back button on top of the form, but don't have any idea how to handle it when users click on sidebar menu options. (there is a sidebar with multiple links to other components - using react-router).
I have tried something using componentWillunmount() but no luck since component gets unmounted in any case.
If anyone has experience in this I would really need some help.
Try the routerWillLeave hook, here is a example from react-router's documentation:
const Home = withRouter(
React.createClass({
componentDidMount() {
this.props.router.setRouteLeaveHook(this.props.route, this.routerWillLeave)
},
routerWillLeave(nextLocation) {
// return false to prevent a transition w/o prompting the user,
// or return a string to allow the user to decide:
if (!this.state.isSaved)
return 'Your work is not saved! Are you sure you want to leave?'
},
// ...
})
)
https://github.com/ReactTraining/react-router/blob/master/docs/guides/ConfirmingNavigation.md

React Redux Confirming Navigation

I'm trying to achieve a product page, which gives the Administrator an ability to modify the product details by clicking an edit button, but if the Admin tries to leave the page with changes that they have not yet saved, it would confirm that the user wants to leave the page without saving.
Here is what I currently have in my ProductForm.js, which is used by Product.js when Admin clicks edit.
import { browserHistory } from 'react-router';
componentWillReceiveProps() {
browserHistory.listenBefore(location => {
console.log(location);
return 'Are you sure you want to leave the page without saving?';
});
}
The issue with the following code is that when the user opens the edit form, this confirmation message shows on every page transition, even if you're not on the product page.
I am using the following skeleton. https://github.com/erikras/react-redux-universal-hot-example
You can cancel listener like this:
import { browserHistory } from 'react-router';
componentWillReceiveProps() {
const cancelListner = browserHistory.listenBefore(location => {
console.log(location);
cancelListner();
return 'Are you sure you want to leave the page without saving?';
});
}

Categories

Resources