React Data sending issue - reactjs

The scenario is forgotpassword.I have done everything from my backend. The only problem is React.I have manage to read header token.And I would like to send token and new password to my back-end with api. As you see down below I can send password easly. But I dont know how send token from URLSearchParams. Is there any usefull idea for that?
const initialValues = {
password: '',
changepassword: '',
}
export function PasswordConfirm() {
const [loading, setLoading] = useState(false)
const [hasErrors, setHasErrors] = useState<boolean | undefined>(undefined)
const {search} = useLocation()
useEffect(() => {
const query = new URLSearchParams(search)
const token = query.get('token')
console.log(token)
},)
const formik = useFormik({
initialValues,
validationSchema: PasswordConfirmSchema,
onSubmit: (values, {setStatus, setSubmitting}) => {
setLoading(true)
setHasErrors(undefined)
setTimeout(() => {
requestPasswordConfirm(values.changepassword,values.password)
.then(({data: {result}}) => {
setHasErrors(false)
setLoading(false)
})
.catch(() => {
setHasErrors(true)
setLoading(false)
setSubmitting(false)
setStatus('The login detail is incorrect')
})
}, 1000)
},
})
export function requestPasswordConfirm(token:string,password:string) {
return axios.post<{result: boolean}>(REQUEST_PASSWORD_URL, {
token,
password
})
}

Related

FIrebase react hooks only when a statement is true

I'm trying to make a Context API that supplies a connected user (not in Firebase Auth) and its respective DB entry in Firestore. I'm using Magic links as the auth method.
Here's my Provider:
const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
const [signer, setSigner] = useState<ethers.Signer | null>(null);
const [address, setAddress] = useState<string | null>(null);
const [balance, setBalance] = useState<string | null>(null);
const [userDoc, dbLoading] = useCollection(
query(
collection(firestore, "users"),
where("walletAddress", "==", address ?? "") // issue is here <----
)
);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isConnected, setIsConnected] = useState<boolean>(false);
useEffect(() => {
if (!dbLoading && userDoc?.empty) {
addDoc(collection(firestore, "users"), {
walletAddress: address,
});
}
setIsLoading(false);
}, [dbLoading]);
const connect = () => {
setIsLoading(true);
provider
.listAccounts()
.then((accounts) => {
if (accounts.length > 0) {
const signer = provider.getSigner(accounts[0]);
setSigner(signer);
signer.getAddress().then((address) => {
setAddress(address);
});
signer.getBalance().then((balance) => {
setBalance(balance.toString());
});
setIsConnected(true);
}
})
.catch((error) => {
console.log(error);
});
};
const disconnect = () => {
setIsLoading(true);
magic.connect
.disconnect()
.then(() => {
setAddress(null);
setBalance(null);
setIsConnected(false);
})
.catch((error) => {
console.log(error);
})
.finally(() => {
setIsLoading(false);
});
};
return (
<AuthContext.Provider
value={{
userDoc: userDoc?.docs[0]?.data() ?? {},
address,
balance,
isLoading: isLoading || dbLoading,
isConnected,
connect,
disconnect,
}}
>
{children}
</AuthContext.Provider>
);
};
So the problem I'm having is quite straight forward: when the user is not logged in, it creates a new entry with 'walletAddress' of null. Before, I had the same Auth Provider as above, just stripped of all the Firestore logic. But after running into some issues when creating Route Guards, I decided to put it all into a single Provider. Is there a simple solution to this, or do I need to go back to two providers and work from there?

React Firebase is not returning error message even after giving wrong input

I am using React Firebase hook to log in to my website. when trying to log in with the wrong email or password in the login form, an error message will be returned from the React firebase hook. But even after giving the wrong input, an error message is not returning
const Login = () => {
const [signInWithEmailAndPassword, error] =
useSignInWithEmailAndPassword(auth);
const location = useLocation();
const navigate = useNavigate();
const from = location?.state?.from?.pathname || '/';
if (error) {
return (
<div>
<p>Error: {error.message}</p>
</div>
);
}
const handleLogIn = (e) => {
e.preventDefault();
const email = e.target.email.value;
const password = e.target.password.value;
signInWithEmailAndPassword(email, password)
e.target.reset();
navigate(from, { replace: true })
}
You are using signInWithEmailAndPassword hook incorrectly.
signInWithEmailAndPassword returns an array & 3th index is of error message.
You can follow this: https://github.com/CSFrequency/react-firebase-hooks/blob/master/auth/README.md#usesigninwithemailandpassword
const [
signInWithEmailAndPassword,
user,
loading,
error,
] = useSignInWithEmailAndPassword(auth);
Since, useSignInWithEmailAndPassword returns an Array, We need to extract/destructure the value from respective index.
Apart from that, You must also use loading to display whether firebase is still authorizing the request or not (Loading State).
The signInWithEmailAndPassword appears to be an async function and your code isn't waiting for the returned Promise to resolve. I'm guessing you are seeing the navigate("/"); called and the app is navigating to the home page.
const handleLogIn = (e) => {
e.preventDefault();
const email = e.target.email.value;
const password = e.target.password.value;
signInWithEmailAndPassword(email, password); // <-- no waiting for promise
e.target.reset();
navigate(from, { replace: true }); // <-- navigate away
};
useSignInWithEmailAndPassword
export default (auth: Auth): EmailAndPasswordActionHook => {
const [error, setError] = useState<AuthError>();
const [loggedInUser, setLoggedInUser] = useState<UserCredential>();
const [loading, setLoading] = useState<boolean>(false);
const signInWithEmailAndPassword = async (
email: string,
password: string
) => {
setLoading(true);
setError(undefined);
try {
const user = await firebaseSignInWithEmailAndPassword(
auth,
email,
password
);
setLoggedInUser(user);
} catch (err) {
setError(err as AuthError);
} finally {
setLoading(false);
}
};
const resArray: EmailAndPasswordActionHook = [
signInWithEmailAndPassword,
loggedInUser,
loading,
error,
];
return useMemo<EmailAndPasswordActionHook>(() => resArray, resArray);
};
The handleLogin handler should probably wait for the Promise to settle so any errors can be returned by the hook. It turns out though that signInWithEmailAndPassword also doesn't return any resolve/rejected values, so there's no way to know the authentication was successful from within the handleLogIn callback function, the component will need to use the hook's returned loading and loggedInUser states to determine if it is safe to navigate.
Example:
const Login = () => {
const [
signInWithEmailAndPassword,
loggedInUser,
loading,
error,
] = useSignInWithEmailAndPassword(auth);
const location = useLocation();
const navigate = useNavigate();
const from = location?.state?.from?.pathname || '/';
useEffect(() => {
if (!loading && loggedInUser) {
navigate(from, { replace: true });
}, [loggedInUser, loading, navigate, from]);
if (error) {
return (
<div>
<p>Error: {error.message}</p>
</div>
);
}
const handleLogIn = (e) => {
e.preventDefault();
const email = e.target.email.value;
const password = e.target.password.value;
signInWithEmailAndPassword(email, password)
e.target.reset();
}
...

Somebody knows how to populate this field showing in the picture below with specific data object?

this is the image(click here!) where you can see our web page with certain fields, that one of the field with arrow is the one didn't populate object from the backend
this is written with react & typescript & our backend is java springboot & MySQL as database.
and here is the code that i'm suspected , having a issue:
const AddUsers: FC = (props) => {
const navigate = useNavigate();
// const { id } = useParams();
const dispatch = useDispatch();
const roleList = useGetRoleList()
const user = useCurrentUser();
const [rolesInput, setRolesInput] = useState<MultiValue<{ value: string; label: string; }>>([]);
const isFetching = useInviteUserLoading()
const permitted = useCheckPermission(ROLES.ADD_USER)
const { register, handleSubmit, formState: { errors }, clearErrors, reset } =
useForm<IUserForm>({ //'resetField'
mode: "onChange",
resolver: yupResolver(userFormSchema)
});
useEffect(() => {
window.scrollTo({ top: 0, behavior: 'smooth' });
}, [])
//fetching list from backend.. <--------
useUpdateEffect( () => {
dispatch( getRolesList({companyId: user.companyId}) );
},[user.companyId])
useUpdateEffect(() => {
clearErrors()
reset();
}, [isFetching])
const onSubmit: SubmitHandler<IUserForm> = (data)=>{
const roles = rolesInput.map(role => parseInt(role.value))
if(roles){
dispatch(inviteUser({
companyId: user.companyId,
roles: roles,
firstName: data.firstName,
lastName: data.lastName,
email: data.email
}))
}else{
alert("Please assign roles")
}
}

How to use RTK query under useEffect?

I have a situation where I tried to fetch data when user login , and my structure is I have two redux slice one is userData other one is UserCartData and
when user login ,if login success ,
then I will dispatch data into UserData ,
3, then I write a useEffect to check if there's userData ,
I will then fetch UserCartData with UserData
But the thing is I can't get useGetxxxQuery work under useEffect,here's my code
const Login = () => {
const user = useAppSelector(state=> state.auth);
const dispatch = useAppDispatch();
const [login] = useLoginMutation();
const [showPassword,setShowPassword] = useState<boolean>(false);
useEffect(() => {
if (user!==null){ //fecth userCart data with userData
const {data ,isLoading,isFetching }= useGetCartByIDQuery(user.user?._id!)
}
}, [dispatch])
return (
<Container>
<Wrapper>
<Title>SIGN IN</Title>
<Formik
initialValues={{ email: "", password: "" }}
validationSchema={Yup.object({
password: Yup.string()
.min(8, 'Must be 8 characters or higher')
.required(),
email: Yup.string().email('Invalid email address').required(),
})}
onSubmit = { async (values, actions) => {
try{
const result = await login(values);
if("data" in result){
//console.log(result.data.data)
dispatch(setCredentials({user:result.data.data.findUser,token:result.data.data.cookie}))
}else{
const err = (result.error as RequestError).data.message
if(err.includes("password")){
actions.setErrors({password:err})
}else if(err.includes("Facebook")){
actions.setErrors({email:err})
}
}
}catch(err){
console.log(err)
}
}}>
//....unrelevant code
You don't need a useEffect here, you can simply use skipToken:
import {skipToken} from '#reduxjs/toolkit/query'
const {data, isLoading, isFetching } = useGetCartByIDQuery(user.user ? user.user._id : skipToken)
You can not use hooks inside other hooks. It is a rule!!! Source: https://reactjs.org/docs/hooks-rules.html Instead of this you can change useGetCartByIDQuery hook and use only a function from there: ex: const { startFetch } = useGetCartByIDQuery
useEffect(() => {
startFetch('your arguments')
}, [])

React typescript app how to stop logouts in refresh?

I am working in a react app built with typescript which takes Django api for log in. I am storing the json web token in my local storage. But the app still logs out automatically when I refresh the page.
Here is what I have done
Django urls.py
path('login/', obtain_jwt_token),
This api is called in react logInContainer. I am saving the token in my local storage.
const logInContainer: React.FC = () => {
const dispatch = useDispatch();
const api = new Api();
const [username, setUsername] = React.useState('');
const [password, setPassword] = React.useState('');
const [errorText, setError] = React.useState('');
const signIn = async () => {
const res = await api.post('/login/', {
username: username,
password: password,
});
const json = JSON.stringify(res);
localStorage.setItem("user-info", json);
if (res) {
dispatch(logInAction(res.token));
} else {
setError('login failed');
}
}
My logInAction
export const LogInAction = (token: string): AuthTypes => {
return {
type: AuthTypes.logIn,
payload: {
token: token,
}
};
};
My authTypes.ts
export const AuthTypes= {
logIn: "SIGN_IN",
logOut: "SIGN_OUT",
} as const;
So far, the login works fine. and the token is also stored in local storage. But whenever I refresh my page, the app log outs automatically. I need to solve this issue. Any help regarding this will be appreciated.
Here is how logout happens
const logOut = async () => {
dispatch(logOutAction())
};
This is called by
<IconButton onClick={logOut}>
<ExitToApp />
</IconButton>
here is logOutAction
export const logOutAction = (): AuthTypes => {
return {
type: ActionTypes.logOut,
};
};
In my reducer ts
import { AuthState, AuthTypes } from "./types";
const initialState: AuthState = {
token: '',
isSignIn: false,
};
Which goes to authTypes
case ActionTypes.signIn:
return Object.assign({}, state, action.payload, { isSignIn: true });
Could you please try to change your reducer code as given below
import { AuthState, AuthTypes } from "./types";
const initialState: AuthState = {
token : localStorage.getItem('token')? localStorage.getItem('token') : '',
isSignIn : localStorage.getItem('token')? true : false,
};

Resources