Share session data across multiple tabs - reactjs

I have a simple login with Remember me checkbox. When a user clicks remember me I store user data and token in localStorage, when the user does not check the Remember me I store user data and token in sessionStorage. I have configured to share session data across multiple tabs also. But when I open the 4th tab or 5th tab I run into an infinite loop in eventListner
Here is my logic.
window.addEventListener('storage', event => util.sessionStorageTransfer(event, sessionData, setSessionData, sessionLogout), false);
util.js
sessionStorageTransfer(event, sessionData, setSessionData, sessionLogout) {
if (!event.newValue) {
return;
}
if (event.key === 'REQUESTING_SHARED_CREDENTIALS') {
window.localStorage.setItem('SHARING_AUTH', JSON.stringify(sessionData));
window.localStorage.removeItem('SHARING_AUTH');
}
if (event.key === 'SHARING_AUTH') {
console.log(event.key);
if (event.newValue) {
setSessionData(JSON.parse(event.newValue));
}
}
if (event.key === 'REQUESTING_LOGOUT') {
sessionLogout();
}
}
I have console log the point that infinite loop occurs. How can I solve this issue?

Related

If user exit app and when open it start with first screen react native?

Issues:
I completed steps till adding the profile information and moved to the next screen which is contact information. I closed the app and opened it again....The app shows that I have created the profile now i need to do the next steps
Expected Result:
If the user leaves the process of profile creation, start over.
so what you can do is :
In async storage, you can save the page name last where the user visited and data was stored and api responded succesfully, (https://react-native-async-storage.github.io/async-storage/docs/usage_
like :
const callApi = (pageName) => {
const result = await api()
//on sucess
if(result.status === 200){
//store page name like this
await AsyncStorage.setItem('#page_name', pageName)
}
}
Then next time when you come back to app, check what page user was on last:
like :
const checkForPageName = async() => {
const value = await AsyncStorage.getItem('#page_name')
if(value !== null) {
if(value === "secondpage"){
navigation.navigate("secondpage");
}
if(value === "thirdpage"){
navigation.navigate("thirdpage");
}
} else{
// this is first time user is coming
navigation.navigate("FirstPage");
}
}
Hope it helps, feel free for doubts

My dapp doesn't detect when an user change their Metamask Account

I am in the process of building a dapp for a project. I have one last thing to adjust: detect when a user changes metamask account to reset the state but it doesn't work.
//Doesn't work
window.ethereum.on('accountsChanged', function (accounts) {
console.log('accountsChanges', accounts);
setDefaultAccount(null);
});
// This works perfectly
window.ethereum.on('chainChanged', (chainId) => {
if(chainId !== "0x13881") {
setErrorMessage("Please connect on testnet Polygon Mumbai");
} else {
setErrorMessage(null);
window.location.reload();
}
});
I was also struggling with the same issue. Being unable to find the answer in the docs anywhere.
Until I'd realized that it's not meant to detect you switching from a connected account to a disconnected one.
In other words: it only detects it when you switch between accounts that are already connected to your Dapp. In that case - it functions perfectly. And detects an account change.
Go on ahead an test it on some popular Dapp out there. Connect just one of your accounts to it - then change it to another account on the same wallet, that is not yet connected - and it will also not be able to detect you changing it.
But if you connect two accounts right away - it will detect you switching between them and reflect your changes on its interface.
I tested this with PCS.
this is the correct way of implementation:
useEffect(() => {
ethereum?.on("accountsChanged", handleAccountChange);
return () => {
ethereum?.removeListener("accountsChanged", handleAccountChange);
};
});
Now write a listener for account change
const handleAccountChange = (...args) => {
// you can console to see the args
const accounts = args[0] ;
// if no accounts that means we are not connected
if (accounts.length === 0) {
console.log("Please connect to metamask");
// our old data is not current connected account
// currentAccount account that you already fetched and assume you stored it in useState
} else if (accounts[0] !== currentAccount) {
// if account changed you should update the currentAccount so you return the updated the data
// assuming you have [currentAccount,setCurrentAccount]=useState
// however you are tracking the state currentAccount, you have to update it. in case of redux you have to dispatch update action etc
setCurrentAccount(accounts[0)
}
};

Handling events when using youtube iframe and socket.io

I'm creating an app where two users can watch a youtube video in real time using socket.io. In theory, all of the users will be also to use the video player controls, but an infinite loop occurs if one of the users press play/pause button multiple times in quick succession. How could I prevent this from happening?
Server code:
socket.on("player status", playerStatus => {
socket.broadcast.emit("status", playerStatus)
})
Client-side code:
useEffect(() => {
socketRef.current = io.connect('/');
socketRef.current.on("status", status => {
if (status === 1) {
youtubePlayer.current.playVideo();
} else {
youtubePlayer.current.pauseVideo();
}
})
}, []);
function onPlayerStateChange(e) {
if (e.data === 1 || e.data === 2) {
socketRef.current.emit("player status", e.data)
}
}

Send "removeUser" request only on window close and not page refresh

I am working on a Chat Application using socket.io/ReactJS. I am facing an issue wherein I need to remove a particular user(String value - Just a username) from the backend(NodeJS/ExpressJS) on Browser window close and not page refresh. As I am using redux-persist(Session Storage) I want to persist the user state when the window is refreshed, but when the user closes the browser window the user will be removed from the backend and obviously from session storage too.
In my App.js file I have below code to register for an event :
removeUserBeforeUnload = () => {
if (window.performance.navigation.type !== 1)
// The socket request which removes the username from the backend
socket.emit("removeUser", this.props.currentUser);
};
setupBeforeUnloadListener = () => {
window.addEventListener("beforeunload", ev => {
ev.preventDefault();
return this.removeUserBeforeUnload();
});
};
componentDidMount() {
// Registering event
this.setupBeforeUnloadListener();
}
I tried using window.performance.navigation.type but that doesn't seem to work.
Thanks for any help.

PUT - Web API controller

I have a put method inside my web API controller. The site has a view mode and an edit mode. When the user is in Edit mode it should save the data into the database(because there are currency changes). When the user is on the view mode page it will still calculate the currency changes but it shouldn't be saved into the database.
So inside my method I have a condition in which mode the user is. When it is edit mode it should calculate and save it. When the user is in view mode it only should calculate it and return the object so I can use it client side.
if (isEditMode)
{
_currencyConversionService.ApplyCurrencyRateToCarearRequest(request);
_requestRepository.Save(request);
}
else
{
_currencyConversionService.ApplyCurrencyRateToCarearRequest(request);
}
return Ok(request);
In edit mode the data is saved when the user clicks the confirmation button. But I'm getting an error clientside though:
net::ERR_SPDY_PROTOCOL_ERROR
Is this because I just return the request inside the Ok() that i'm getting this error or why do I get this one? I'm ending up into the catch from this code:
this.service.save(this.model, this.isEditMode)
.then((response: any) => {
debugger;
this.messageService.success('request.notifications.currencySaved');
this.close();
this.$timeout(() => {
this.$window.location.reload();
}, 1000);
}).
catch((reason: any) => {
debugger;
});
How can I return an object inside a PUT method?
Thanks, Brent

Resources