hi , i have this kind of problem .. in my code i should pass the User name dynamicaly
here is my DashBoard wher i should pass the user name like "welcome ,UserName"
const Dashboard = ({logoutUser, user}) => {
const history = useHistory();
console.log("Dashboard user", user)
//here in console i can see the username that i pass
return (
<StyledFromArea bg={colors.dark2}>
<StyledTitle size={65}>Welcome : {user.name }
{ console.log("user.name", user.name)}
</StyledTitle>
{ // but here in console returning undefined , why? }
<Userinfo/>
<ButtonGroup>
<StyledButton to="#" onClick={() => logoutUser(history)}>Logout</StyledButton>
</ButtonGroup>
</StyledFromArea>
</div>
)
}
const mapStateToProps = ({session}) => ({
user: session.user,
});
export default connect(mapStateToProps, {logoutUser})(Dashboard)
//in logout acton i just deleting the sessionService.deleteSession()
//sessionService.deleteUser() and redirect to the home page
Related
There is a React component which contains list of users and form to invite a new user.
"inviteNewUser" is a *POST* request in backend
"getUsers" is a *GET* request to get all users
The problem is that after clicking on button "Invite User" I would like to see the invited user in the list of users ("currentUsers" in code below) without refreshing the page. But right now it happens only after I refresh the whole page.
when I'm trying to make a GET request to get all users right after inviteNewUser(data) (POST request) I'm getting the "old" user list without user which I just invited. So the "currentUsers" list is not immediately updated
Could someone help me to fix this issue ?
export function MyForm({
getUsers,
inviteNewUser,
userId,
currentUsers
}) {
useEffect(() => {
getUsers(userId);
}, [userId]);
function handleSendInvite(data) {
inviteNewUser(data);
getUsers(data.userId);
}
return (
<>
{currentUsers.map((user) => (
<UserItem
key={user.userId}
user={user}
/>
))}
<Button
text="Invite User"
onClick={() => {
handleSendInvite({userId});
}}
/>
</>);
}
MyForm.propTypes = {
getUsers: PropTypes.func.isRequired,
inviteNewUser: PropTypes.func.isRequired,
userId: PropTypes.number.isRequired,
currentUsers: PropTypes.arrayOf(UserInfo),
};
const mapStateToProps = (state) => {
const { id } = routerParamsSelector(state);
const currentUsers = selectCurrentUsers(state);
return {
userId: parseInt(id, 10),
currentUsers,
};
};
const mapDispatchToProps = {
getUsers,
inviteNewUser
};
export default connect(mapStateToProps, mapDispatchToProps)(MyForm);
Try async and await, it works.
const handleSendInvite = async (data) {
await inviteNewUser(data);
getUsers(data.userId);
}
It should be user instead of userId as you access the property of the object in the function.
<Button text="Invite User" onClick={() => { handleSendInvite(user); }} />
------------------------------------------------------------------------
const handleSendInvite = async (data) {
await inviteNewUser(data);
getUsers(data.userId);
}
here is my code in redux ,everythig is fine the code are working
export const loginUser = (values, history, setFieldError, setSubmitting) => {
i take **email**, split it until # and take it as a username ,
const username = values.email.split("#")[0]
return () => {
//then i pass it to axios params as a query name
axios.get(url, {
params: {
name: username
}
}).then((response) => {
//if res ok
console.log("username", username)
history.push("/user")
}).catch(error => console.error(error))
setSubmitting(false);
}
}
now i should pass that usernam as a props to my Dashboard witch is a component
const Dashboard = ({logoutUser,user}) => {
const history = useHistory();
return (
<StyledFromArea bg={colors.dark2}>
here i need to show a *username*
should be like **Hello , YourName**
<StyledTitle size={65}>Hello, {user.user}
//but its undefided
{console.log("user",user.name)}
</StyledTitle>
*same here*
<ExtraText color={colors.light1}>{user.email}</ExtraText>
{console.log("email",user.email)}
<Userinfo/>
<ButtonGroup>
<StyledButton to="#" onClick={()=> logoutUser(history)}> Logout
</StyledButton>
</ButtonGroup>
</StyledFromArea>
)
}
//i use **mapStateToProps**but maybe it's not working ,i think the //problem comes from here
const mapStateToProps =({session})=>({
user:session.user
})
export default connect(mapStateToProps,{logoutUser})(Dashboard) ;
my code
https://codesandbox.io/s/login-page-forked-6gcvq?file=/src/pages/Dashboard.js
First you must use connect with class componets but you use functional style. SeŃond in session absent your user data, you must create another reducer for user. Demo
This is my first time using firestore and I have a react app where I want to display the logged user's username. I try to fetch the username from a firestore DB where I query users using the email of the user.
firebase.js
export const GetUserName = (email)=>{ //get single doc by email
let name = []; //store the name
//this is where the problem begins
db.collection('users').where("Email", "==" ,email)
.get()
.then(snapShot=>{
snapShot.forEach((snap)=>{
name.push(snap.data().userName); //stores only in array temporarily
console.log(name) //shows correct array
});
})
.catch(err =>{
console.log(err);
})
console.log(name); //shows empty array
return name[0]; //array is empty
}
then I try to display the username in another component I have
profilePage.js
import {GetUserName} from '../firebase';
export default function ProfilePage(){
const {user , logout} = useAuth(); //this is access to user.email
return (
<div>
<h1>Hi {getUsername(user.email)} </h1>
<Button onClick={handleLogout} color = "primary" variant = "outlined">Log out</Button>
</div>
);
}
But I only get "hi" without the username
Since the user name is read from Firestore asynchronously by the time your return name[0] runs, the name.push(snap.data().userName); hasn't run yet. You can easily check this by setting breakpoints on these lines and running the code in a debugger.
In situations like this you need to pass the data to the rendering code by putting it in the component's state. Using the useState hook that'd be:
import {GetUserName} from '../firebase';
export default function ProfilePage(){
const {user , logout} = useAuth(); //this is access to user.email
const [userName, setUsername] = useState();
useEffect(() => {
db.collection('users').where("Email", "==" ,user.email)
.get()
.then(snapShot=>{
snapShot.forEach((snap)=>{
setUsername(snap.data().userName);
});
})
.catch(err =>{
console.log(err);
})
});
return (
<div>
<h1>Hi {userName} </h1>
<Button onClick={handleLogout} color = "primary" variant = "outlined">Log out</Button>
</div>
);
}
So i've basically got 2 components on my page.
First is the search component where the users need to type their username and second one where their stats get displayed
and here is my API request call in App.js
useEffect(()=>{
const fetchStats = async ()=> {
const result = await axios.get(`https://cors-anywhere.herokuapp.com/https://public-api.tracker.gg/v2/csgo/standard/profile/steam/${username}`,
{
headers: {
'TRN-Api-Key' : '***************************',
}
}
)
if(username !== null){
console.log(result.data)
setStats(result.data)
}
}
fetchStats()
},[username])
and this is the search component
const Search = ({setInputText, setUsername, inputText, username}) => {
const inputHandler = (e)=> {
setInputText(e.target.value)
}
const searchHandler = (e)=> {
e.preventDefault()
setUsername(inputText)
}
return (
<div>
<form>
<input value={inputText} onChange={inputHandler} type="text"/>
<button onClick={searchHandler}>Search</button>
</form>
</div>
)
}
What i'm having an issue with is when i click a button in the username component the value(username) from the form gets stored in the 'username' state in App.js. Now i'm using this code in the stats component.
const Stats = ({stats}) => {
return (
<div>
<h1>{stats.data.platformInfo.platformUserHandle}</h1>
</div>
)
}
export default Stats
Here stats.data.platformInfo.platformUserHandle doesn't exist when the app starts so it gives me a LOT of errors. How do i keep the app from crashing till the user has input something and data can be sent to the stats component?
I'm using the npm module aws-cognito-next to implement authentication for one of my app. There the function getServerSideAuth(context.req); seems to not working as expected:
export async function getServerSideProps(context) {
// getServerSideAuth will parse the cookie
const initialAuth = getServerSideAuth(context.req);
return { props: { initialAuth } };
}
Then in the same page which is Home (/pages/home.js) I use this returned initialAuth as follows:
const Register = ( {initialAuth} ) => {
console.log("initialAuth is: " + util.inspect(initialAuth))
const auth = useAuth(initialAuth);
...
//other logic
...
}
But I get out put as: initialAuth is: null. So why doesn't initialAuth isn't getting returned from serverside? What am I doing wrong here?
getServerSideAuth checks to see if user is logged in and returns tokens that can be used in useAuth. You can check for null and add logic to send the user to the login/logout pages.
const Register = ( {initialAuth} ) => {
const auth = useAuth(initialAuth);
const { login, logout } = useAuthFunctions();
return (
<React.Fragment>
{auth ? (
<button type="button" onClick={() => logout()}>
sign out
</button>
) : (
<React.Fragment>
<button type="button" onClick={() => login()}>
sign in
</button>
</React.Fragment>
)}
</React.Fragment>
);
}
For more information on useAUth see here.