Not able to access session storage while page routing in reactjs - javascript

When I am routing my page on sign up submit, then I am submitting the email in sessionStorage.
But while getting the item from session storage I am not able to do so. My page is routing to another page after submission of sign up.
import React, { Component } from "react";
import { Link } from "react-router-dom";
import axios from "../axios/axios.js";
export class SignUpRedirect extends Component {
constructor() {
super();
this.state = {
U_Id: null,
isLoading: true,
};
}
async componentDidMount() {
const response = await axios.get("/Organization");
const idData = response.data;
idData.forEach((item) => {
if (item.Email === sessionStorage.getItem("email")) {
this.setState({ U_Id: item.U_Id, isLoading: false });
}
});
}
componentWillUnmount() {
this.setState = (state, callback) => {
return;
};
}
render() {
return (
<div className="donestatus-container">
You Have Signed Up And Your Organization Id is :{" "}
{this.state.isLoading ? "...loading" : this.state.U_Id}
<div className="donestatus-container-inner">
<Link to="/sign-in">
<h4>Sign In</h4>
</Link>
</div>
</div>
);
}
}
export default SignUpRedirect;
I am not able to find suitable answer. Can anyone help me out?

Try below code, as you need to parse sessionStorage object, which is like a JSON Onject:
async componentDidMount() {
const response = await axios.get("/Organization");
const idData = response.data;
idData.forEach((item) => {
if (item.Email === JSON.parse(sessionStorage.getItem("email"))) {
this.setState({ U_Id: item.U_Id, isLoading: false });
}
});
}

Related

Why history listen is not updating my component's state?

TLDR: I am building a React router app, I trying to update the state of my component through a history listener, this listener works fine I put a console.log and I can see it, but the state of my component is not changing, I can see this with the React chrome extension and my component is not updating.
`
import React from "react";
import { withRouter } from "react-router-dom";
import { styles } from './Styles';
import { url } from './App';
class Searchresults extends React.Component {
constructor(props) {
super(props);
this.state = {
searchResults : []
}
}
async fetchResults(endpoint) {
try {
const response = await fetch(endpoint);
if (response.ok) {
const rJson = await response.json();
return rJson;
}
} catch (err) {
console.log(err);
}
}
componentDidMount() {
this.searchUpdate();
this.unlisten = this.props.history.listen((location, action) => {
console.log("it works!");
this.searchUpdate();
})
}
searchUpdate = () => {
const { location } = this.props;
const params = new URLSearchParams(location);
const query = params.get("search");
const name = query.replace("?name", "s");
const endpoint = url + "&" + name;
this.fetchResults(endpoint).then(response => {
return response['Search'].map(item => {
return { title: item['Title'], poster: item['Poster'], id: item['imdbID'] }
})
}).then(response => {
this.setState({
searchResults : response
})
});
}
render() {
return (
<div style={styles.movieList}>
<ul>
{
!this.state.searchResults? 'Loading' : this.state.searchResults.map((item, index) => {
return (<li key={index}>
<a href={'/moviepage?id=' + item.id}>{item.title}</a><br />
<img src={item.poster} alt="Movie poster"
style={{ width: "6rem", height: "auto" }} />
</li>)
})
}
</ul>
</div>
);
}
}
export default withRouter(Searchresults);
`
I am trying to update the state with a method searchUpdate, then this method is called in componentDidMount, here works fine, then when the URL changes, the history.listen triggers and searchUpdate is fired again, and everything seems to work except the change of the state of my component.
The first .then function in your searchResult function doesn't return a promise, so there is no need to use another .then. Just put the setState call in the same block:
this.fetchResults(endpoint).then(response => {
const searchResults = response['Search'].map(item => {
return { title: item['Title'], poster: item['Poster'], id: item['imdbID'] }
});
this.setState({searchResults})
});

Getting my userName from MS teams with javascript/reactjs

Im trying to get my Teams userPrincipalname out of the context and using it in a fetch URL. Unfortunately its not actually saving my userPrincipalName within {userPrincipalName} but instead it contains: [object Object]
As i can see in the URL its trying to fetch: http://localhost/openims/json.php?function=getDocuments&input=%22[object%20Object]%22
The URL returns the following: {"name":"[object Object]","age":26,"city":"London"}
What am i doing wrong here?
The code:
import React from 'react';
import './App.css';
import * as microsoftTeams from "#microsoft/teams-js";
class Tab extends React.Component {
constructor(props){
super(props)
this.state = {
context: {}
}
}
componentDidMount(){
microsoftTeams.getContext((context, error) => {
this.setState({
context: context
});
});
}
componentDidMount() {
const { userPrincipalName } = this.state.context;
fetch('http://localhost/openims/json.php?function=getDocuments&input='+'"'+ {userPrincipalName} +'"')
.then(res => res.json())
.then((result) => {
this.setState({ ...result });
})
.catch((error) => {
this.setState({ error });
})
.finally(() => {
this.setState({ isLoaded: true })
});
}
render() {
const { error, isLoaded, name, age, city } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
<li>
{name} {age} {city}
</li>
</ul>
);
}
}
}
export default Tab;
The problems I can see are that you need to ensure:
microsoftTeams.getContext takes a callback, so promisify it and then you use then on it (like any promise)
once you've got the context, create a URL dynamically using the value of context.userPrincipalName
the final fetch request (to /openims/json.php endpoint) only happens once all of the above has happened
That should be something like the following (although re-writing your component as functional component would allow you to use React hooks and better handle any cleanup required).
import React from "react";
import "./App.css";
import * as microsoftTeams from "#microsoft/teams-js";
class Tab extends React.Component {
constructor(props) {
super(props);
this.state = { context: {} };
}
componentDidMount() {
new Promise((resolve) => {
microsoftTeams.getContext(resolve);
})
.then((context) => {
this.setState({ context });
const queryParameters = new URLSearchParams({
function: "getDocuments",
input: `"${context.userPrincipalName}"`,
});
console.log(`userPrincipalName is '${context.userPrincipalName}'`);
return fetch(`http://localhost/openims/json.php?${queryParameters}`);
})
.then((res) => res.json())
.then((result) => this.setState({ ...result }))
.catch((error) => this.setState({ error }))
.finally(() => this.setState({ isLoaded: true }));
}
render() {
const { error, isLoaded, name, age, city } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
<li>
{name} {age} {city}
</li>
</ul>
);
}
}
}
export default Tab;
Could you please try with below working code.
import React from 'react';
import * as microsoftTeams from "#microsoft/teams-js";
class Tab extends React.Component {
constructor(props){
super(props)
this.state = {
context: {}
}
}
//React lifecycle method that gets called once a component has finished mounting
//Learn more: https://reactjs.org/docs/react-component.html#componentdidmount
componentDidMount(){
// Get the user context from Teams and set it in the state
microsoftTeams.getContext((context, error) => {
this.setState({
context: context
});
});
// Next steps: Error handling using the error object
}
render() {
let userName = Object.keys(this.state.context).length > 0 ? this.state.context['upn'] : "";
return (
<div>
<h3>Hello World!</h3>
<h1>Congratulations {userName}!</h1> <h3>This is the tab you made :-)</h3>
</div>
);
}
}
export default Tab;

how to save react js state into localstorage

I have no idea How to store the react js state into localstorage.
import React, { Component } from 'react'
import './App.css';
import { auth,createUserProfileDocument } from './firebase/firebase.utils'
import { TodoForm } from './components/TodoForm/TodoForm.component'
import {TodoList} from './components/TodoList/TodoList.component'
import {Footer} from './components/footer/footer.component'
import Header from '../src/components/header/header.component'
import {Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
import {setCurrentUser} from './redux/user/user.actions'
export class App extends Component {
constructor(props) {
super(props)
this.input=React.createRef()
this.state = {
todos:[
{id:0, content:'Welcome Sir!',isCompleted:null},
]
}
}
todoDelete = (id) =>{
const todos = this.state.todos.filter(todo => {
return todo.id !== id
})
this.setState({
todos
})
}
toDoComplete = (id,isCompleted) =>{
console.log(isCompleted)
var todos = [...this.state.todos];
var index = todos.findIndex(obj => obj.id === id);
todos[index].isCompleted = !isCompleted;
this.setState({todos});
console.log(isCompleted)
}
addTODO = (todo) =>{
todo.id = Math.random()
todo.isCompleted = true
let todos = [...this.state.todos, todo]
this.setState({
todos
})
}
unsubscribeFromAuth = null;
componentDidMount() {
const { setCurrentUser } = this.props;
this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => {
if (userAuth) {
const userRef = await createUserProfileDocument(userAuth);
userRef.onSnapshot(snapShot => {
setCurrentUser({
id: snapShot.id,
...snapShot.data()
});
});
}
setCurrentUser(userAuth);
});
}
componentWillUnmount() {
this.unsubscribeFromAuth();
}
render() {
return (
<div className='App'>
<Header />
<TodoForm addTODO={this.addTODO} />
<TodoList
todos={this.state.todos}
todoDelete={ this.todoDelete}
toDoComplete={ this.toDoComplete}
/>
<Footer/>
</div>
)
}
}
const mapStateToProps = ({ user }) => ({
currentUser: user.currentUser
});
const mapDispatchToProps = dispatch => ({
setCurrentUser: user => dispatch(setCurrentUser(user))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
in my input Form
import './TodoForm.style.css'
export class TodoForm extends Component {
constructor(props) {
super(props)
this.state = {
content : ''
}
}
handleChange = (e) =>{
this.setState({
content: e.target.value
})
}
handleSubmit =(e) =>{
e.preventDefault();
this.props.addTODO(this.state);
this.setState({
content: ''
})
}
render() {
return (
<div className='inputTask'>
<form onSubmit={ this.handleSubmit}>
<input
className="textBox"
type='text'
onChange={ this.handleChange}
value={this.state.content}
placeholder='what you want to do ...'
/>
</form>
</div>
)
}
}
export default TodoForm
I have no idea How to store the react js state into localstorage.
i searched on internet but unable to find the exact solution all the codes that i think is necessary post.
You can use reactLocalStorage to save any data in local storage
import {reactLocalStorage} from 'reactjs-localstorage';
reactLocalStorage.set('var', true);
reactLocalStorage.get('var', true);
reactLocalStorage.setObject('var', {'test': 'test'});
reactLocalStorage.getObject('var');
reactLocalStorage.remove('var');
reactLocalStorage.clear();
Read out the localStorage item in the componentDidMount callback. Simply read the item you want to get, check if it exists and parse it to a usable object, array or datatype that need. Then set the state with the results gotten from the storage.
And to store it, simply handle it in an event handler or helper method to update both the state and the localStorage item.
class ExampleComponent extends Component {
constructor() {
super();
this.state = {
something: {
foo: 'bar'
}
}
}
componentDidMount() {
const storedState = localStorage.getItem('state');
if (storedState !== null) {
const parsedState = JSON.parse(storedState);
this.setState({ something: parsedState });
}
}
clickHandler = (event) => {
const value = event.target.value;
const stringifiedValue = JSON.stringify(value);
localStorage.setItem('state', stringifiedValue);
this.setState({ something: value });
}
render() {
return (
<button onClick={clickHandler} value={this.state.something}>Click me</button>
);
}
}
Set data in localStorage
key-value pair :
localStorage.setItem('key_name',"value");
object
localStorage.setItem('key_name', JSON.stringify(object));
Remove data from localStorage
localStorage.removeItem('key_name');
Get data from localStorage
let data = localStorage.getItem('key_name');
object :
let data = JSON.parse(localStorage.getItem('key_name'));
clear localStorage (delete all data)
localStorage.clear();

Paypal Checkout button with React not letting signed in

I am having issues integrating the Paypal with my react app using sandbox. When I click on the Button, a pop-up of PayPal opens and when I put in my credentials to log in, I get the following error:
I am able to see the sign in form, but it just won't let me sign in and instead I come to see that message.
App.js
import PaypalButton from './PaypalButton';
const CLIENT = {
sandbox: 'xxxxx',
production: 'xxxxx',
};
const ENV = process.env.NODE_ENV === 'production' ? 'production' : 'sandbox';
render() {
const onSuccess = (payment) =>
console.log('Successful payment!', payment);
const onError = (error) =>
console.log('Erroneous payment OR failed to load script!', error);
const onCancel = (data) =>
console.log('Cancelled payment!', data);
return(
<div>
<PaypalButton
client={CLIENT}
env={ENV}
commit={true}
currency={'USD'}
total={500.00}
onSuccess={onSuccess}
onError={onError}
onCancel={onCancel}
/>
</div>
)
}
PaypalButton
import React from 'react';
import ReactDOM from 'react-dom';
import scriptLoader from 'react-async-script-loader';
class PaypalButton extends React.Component {
constructor(props) {
super(props);
this.state = {
showButton: false,
};
window.React = React;
window.ReactDOM = ReactDOM;
}
componentDidMount() {
const {
isScriptLoaded,
isScriptLoadSucceed
} = this.props;
if (isScriptLoaded && isScriptLoadSucceed) {
this.setState({ showButton: true });
}
}
componentWillReceiveProps(nextProps) {
const {
isScriptLoaded,
isScriptLoadSucceed,
} = nextProps;
const isLoadedButWasntLoadedBefore =
!this.state.showButton &&
!this.props.isScriptLoaded &&
isScriptLoaded;
if (isLoadedButWasntLoadedBefore) {
if (isScriptLoadSucceed) {
this.setState({ showButton: true });
}
}
}
render() {
const {
total,
currency,
env,
commit,
client,
onSuccess,
onError,
onCancel,
} = this.props;
const {
showButton,
} = this.state;
const payment = () =>
paypal.rest.payment.create(env, client, {
transactions: [
{
amount: {
total,
currency,
}
},
],
});
const onAuthorize = (data, actions) =>
actions.payment.execute()
.then(() => {
const payment = {
paid: true,
cancelled: false,
payerID: data.payerID,
paymentID: data.paymentID,
paymentToken: data.paymentToken,
returnUrl: data.returnUrl,
};
onSuccess(payment);
});
return (
<div>
{showButton && <paypal.Button.react
env={env}
client={client}
commit={commit}
payment={payment}
onAuthorize={onAuthorize}
onCancel={onCancel}
onError={onError}
/>}
</div>
);
}
}
export default scriptLoader('https://www.paypalobjects.com/api/checkout.js')(PaypalButton);
Can someone please help me solve this issue?
I had the same issue last week. After working for a while, the sandbox started giving me that error. I reverted all my commits to ensure it wasn't an issue with my code. After a day or two, it started to work again.
Seems it was an issue with PayPal's sandbox environment. (Apparently it happens to the best of us).
If you had been sending incorrect data, you would have seen a console.log of the error.

ReactJs - How to complete onClick before download - href

I have a simple React button component that when clicked should retrieve and download data on the client browser. The problem I am experiencing is that the download is triggered and the csv file downloaded before the data is passed into the href.
Here is my component:
import { Component } from 'react';
import { connect } from 'react-redux';
import { PropTypes } from 'prop-types';
import { ManageUsersSelectors } from 'selectors/Users';
import { BatchRoleActions } from 'actions/Users';
class UsersExportButton extends Component {
constructor() {
super();
this.state = {
users: ''
};
}
getUsers(){
const { userIds } = this.props;
BatchRoleActions.getAllRoleUsers(userIds)
.then((users) => {
this.setState({ users: users});
return this.state.users;
});
}
render() {
return (
<div className="roles-export-button">
<a className="button button-default" href={this.state.users} download={'roles.csv'} onClick={() => this.getUsers()} return true>Export Csv</a>
</div>
);
}
}
function mapStateToProps(state) {
const userIds = ManageUsersSelectors.batchUserIdsSelector(state);
return {
userIds: userIds
};
}
UsersExportButton.propTypes = {
text: PropTypes.string.isRequired,
data: PropTypes.array
};
export default connect(mapStateToProps)(UsersExportButton);
How can I get the getUsers()/onClick function to complete the data retrieval step before downloading?
When i debug my code I can see that the getUsers function returns data - however after the download is triggered
Make sure to bind this to your functions. In your constructor you can do:
constructor() {
super();
this.state = {
users: ''
};
this.getUsers = this.getUsers.bind(this);
}
or you can use the bind this function:
getUsers = () => {
const { userIds } = this.props;
BatchRoleActions.getAllRoleUsers(userIds)
.then((users) => {
this.setState({ users: users});
return this.state.users; // This should be removed, you can use this.state.users throughout this component.
});
}
Why not get the user data in the componentDidMount lifecycle method? It doesn't look like it needs to be called onClick.
{
// ...
componentDidMount() {
this.getUsers();
}
// ...
render() {
return (
<div className="roles-export-button">
<a className="button button-default" href={this.state.users} download={'roles.csv'}>Export Csv</a>
</div>
)
}
}
How about handling the default "link" behaviour manually to get more control? Also you should probably try to access state after setState has been executed via its callback.
e.g.
getUsers(cb){
const { userIds } = this.props;
BatchRoleActions.getAllRoleUsers(userIds)
.then((users) => {
// note the callback of setState which is invoked
// when this.state has been set
this.setState({ users: users }, cb);
});
}
const handleClick = () => {
this.getUsers(() => {
window.open(this.state.whatever)
})
}
<span onClick={handleClick}>Export Csv</span>

Categories

Resources