I want to change password, while I'm logged in.
Here's my function:
authActions.js(without catch because that will be implemented if anything start to works)
// Change password
export const changePassword = (newPassword) => (dispatch, getState) => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json'
}
}
axios.post(`/api/auth/user/changePassword/`, newPassword, tokenConfig(getState))
.then(res => dispatch({
type: CHANGE_PASSWORD,
payload: res.data
}))
}
// Setup config/headers and token
export const tokenConfig = getState => {
// Get token from localstorage
const token = getState().auth.token;
// Headers
const config = {
headers: {
// "Accept": "application/json, multipart/form-data"
"Content-type": "application/json"
}
}
// If token, add to headers
if (token) {
config.headers['x-auth-token'] = token;
}
return config;
}
and authReducer.js:
...
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: false,
user: null
};
export default function (state = initialState, action) {
switch (action.type) {
...
case CHANGE_PASSWORD:
return {
...state,
token: null,
user: action.payload,
isAuthenticated: false,
isLoading: false
};
default:
return state;
}
}
and routes/api/auth.js
router.post('/user/changePassword/', (req, res) => {
console.log(req.body);
const { email, oldPassword, newPassword } = req.body
// find if old password is valid
User.findOne({ email })
.then(user => {
bcrypt.compare(oldPassword, user.password)
.then(isMatch => {
if (isMatch) {
// change to new password
user.password = newPassword
user
.save()
.then(newUser => {
res.status(200).send(newUser)
})
.catch(err => {
const message = err.message
res.status(500).json({
status: "change password failed",
msg: message
})
})
} else {
return res.status(401).send("Invalid old password")
}
})
})
.catch(err => {
res.status(500).send(err)
})
});
I have console.log(req.body); in routes just to check if anything works, but it don't works(didn't give me any message).
And component in the end(but it's not the source of problem):
import React, { useState, useEffect } from 'react';
import {
Button,
Modal,
ModalHeader,
ModalBody,
Form,
FormGroup,
Label,
Input,
NavLink
} from 'reactstrap';
import { connect } from 'react-redux';
import { changePassword } from '../../actions/authActions';
import PropTypes from 'prop-types';
const ChangePassword = ({ auth }) => {
const [modal, setModal] = useState(false);
const [enterPassword, setEnterPassword] = useState({
oldPassword: '',
newPassword: ''
});
const [takeEmail, setTakeEmail] = useState(null);
useEffect(() => {
const createArray = () => {
const { user } = auth;
setTakeEmail({ email: user.email });
};
createArray();
}, [auth.user]);
const toggle = () => {
setModal(!modal);
};
const onChange = e => {
setEnterPassword({
...enterPassword,
[e.target.name]: e.target.value
});
};
const onSubmit = (event) => {
event.preventDefault();
const { email } = takeEmail;
const { oldPassword, newPassword } = enterPassword;
console.log(enterPassword);
console.log(takeEmail);
const newUser = {
email,
oldPassword,
newPassword
}
// Add content via changePassword action
changePassword(newUser);
toggle();
}
return (
<div>
<NavLink onClick={toggle} href="#">
Change Password
</NavLink>
<Modal
isOpen={modal}
toggle={toggle}
className="open-modal"
>
<ModalHeader toggle={toggle}>Dodaj do listy ogłoszeń</ModalHeader>
<ModalBody>
<Form onSubmit={onSubmit}>
<FormGroup>
<Label for="oldPassword">Nagłówek</Label>
<Input
type="password"
name="oldPassword"
id="oldPassword"
placeholder="Wprowadź stare hasło..."
onChange={onChange}
/>
<Label for="newPassword">Nagłówek</Label>
<Input
type="password"
name="newPassword"
id="newPassword"
placeholder="Wprowadź stare hasło..."
onChange={onChange}
/>
<Button
color="dark"
style={{ marginTop: '2rem' }}
block>
Zmień hasło
</Button>
</FormGroup>
</Form>
</ModalBody>
</Modal>
</div>
);
}
ChangePassword.propTypes = {
isAuthenticated: PropTypes.bool,
changePassword: PropTypes.func.isRequired
}
const mapStateToProps = state => ({
auth: state.auth,
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { changePassword })(ChangePassword);
Related
In this page the user can login, but if the untilDate is bigger than the current date it should log out the user. The code runs fine 1/2 times, the other giving me the error on the title.
I am working with createContext for user login. This is the AuthContext file
import React from "react";
import { createContext, useEffect, useReducer } from "react";
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
loading: false,
error: null,
};
export const AuthContext = createContext(INITIAL_STATE);
const AuthReducer = (state, action) => {
switch (action.type) {
case "LOGIN_START":
return {
user: null,
loading: true,
error: null,
};
case "LOGIN_SUCCESS":
return {
user: action.payload,
loading: false,
error: null,
};
case "LOGOUT":
return {
user: null,
loading: false,
error: null,
};
case "LOGIN_FAILURE":
return {
user: null,
loading: false,
error: action.payload,
};
case "UPDATE_USER_DATE":
const updatedUser = { ...state.user };
updatedUser.activeUntil = action.payload;
return {
...state,
user: updatedUser,
};
default:
return state;
}
};
export const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE);
useEffect(() => {
localStorage.setItem("user", JSON.stringify(state.user));
}, [state.user]);
return (
<AuthContext.Provider
value={{
user: state.user,
loading: state.loading,
error: state.error,
dispatch,
}}
>
{children}
</AuthContext.Provider>
);
};
When the user clicks the login button, it runs the handleClick function:
const handleClick = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
let date = new Date().toJSON();
let userdate = date;
try {
const res = await axios.post("/auth/signin", credentials);
dispatch({ type: "LOGIN_SUCCESS", payload: res.data.details });
userdate = user.activeUntil;
//do if date is <=current datem dispatch logout
} catch (err) {
if (userdate > date) {
console.log("undefined data");
} else {
dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
}
}
if (userdate > date) {
dispatch({ type: "LOGOUT" });
console.log("If you are seeing this your contract has expired");
} else {
// navigate("/myinfo");
}
};
The console error happens from this line dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
Is there a way I can bypass this error or a different way I can write my code to make it work?
This is the full code of login page
import React from "react";
import axios from "axios";
import { useContext, useState } from "react";
import { useNavigate } from "react-router-dom";
import { AuthContext } from "../../context/AuthContext";
import {
Container,
FormWrap,
FormContent,
Form,
FormInput,
FormButton,
Icon,
FormH1,
SpanText,
IconWrapper,
IconL,
} from "./signinElements";
import Image from "../../images/Cover.png";
const Login = () => {
const [credentials, setCredentials] = useState({
namekey: undefined,
password: undefined,
});
/* */
// to view current user in console
const { user, loading, error, dispatch } = useContext(AuthContext);
let msg;
const navigate = useNavigate();
const handleChange = (e) => {
setCredentials((prev) => ({ ...prev, [e.target.id]: e.target.value }));
};
const handleClick = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
let date = new Date().toJSON();
let userdate = date;
try {
const res = await axios.post("/auth/signin", credentials);
dispatch({ type: "LOGIN_SUCCESS", payload: res.data.details });
userdate = user.activeUntil;
//do if date is <=current datem dispatch logout
} catch (err) {
if (userdate > date) {
console.log("undefined data");
} else {
dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
}
}
if (userdate > date) {
dispatch({ type: "LOGOUT" });
console.log("If you are seeing this your contract has expired");
} else {
// navigate("/myinfo");
}
};
// console.log(user.activeUntil); //type to view current user in console
return (
<>
<Container>
<IconWrapper>
<IconL to="/">
<Icon src={Image}></Icon>
</IconL>
</IconWrapper>
<FormWrap>
<FormContent>
<Form action="#">
<FormH1>
Sign in with the namekey and password written to you on your
contract.
</FormH1>
<FormInput
type="namekey"
placeholder="Namekey"
id="namekey"
onChange={handleChange}
required
/>
<FormInput
type="password"
placeholder="Password"
id="password"
onChange={handleChange}
/>
<FormButton disabled={loading} onClick={handleClick}>
Login
</FormButton>
<SpanText>{msg}</SpanText>
{error && <SpanText>{error.message}</SpanText>}
{error && (
<SpanText>
Forgot namekey or password? Contact our support team +355 69
321 5237
</SpanText>
)}
</Form>
</FormContent>
</FormWrap>
</Container>
</>
);
};
export default Login;
The problem was i was trying to call a localy stored user and 1 time it wasnt loaded and the other it was. Simply fixed it by changing the if statement to check directly in result details without having to look in local storage.
const [expired, setExpired] = useState(false);
const handleClick = async (e) => {
e.preventDefault();
dispatch({ type: "LOGIN_START" });
try {
const res = await axios.post("/auth/signin", credentials);
dispatch({ type: "LOGIN_SUCCESS", payload: res.data.details });
let date = new Date().toJSON();
if (res.data.details.activeUntil < date) {
dispatch({ type: "LOGOUT" });
console.log("Users contract has expired");
setExpired(!expired);
} else {
navigate("/myinfo");
}
} catch (err) {
dispatch({ type: "LOGIN_FAILURE", payload: err.response.data });
}
};
I have an issue with the login authentication in my project. I connected my react front end with my express back end, but when I try to login with valid credentials, it gets stuck in an error seems like it can't read properly the value I'm passing in my form input.
Here's my LogIn page:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { signin } from '../actions/authAction';
import { clearErrors } from '../actions/errAction';
import { Button, Form, FormGroup, Input, Alert } from 'reactstrap'
import TopCont from '../components/TopCont'
class Signin extends Component {
state = {
email: '',
password: '',
msg: null
};
static propTypes = {
isAuth: PropTypes.bool,
signin: PropTypes.func.isRequired,
err: PropTypes.object.isRequired,
clearErrors: PropTypes.object.isRequired
};
componentDidMount(){
this.props.clearErrors();
}
componentDidUpdate(prevProps){
const { err } = this.props;
if(err !== prevProps.err) {
if(err.id === 'LOGIN_FAIL'){
this.setState({ msg: err.msg.msg });
} else {
this.setState({ msg: null });
}
}
};
onChange = e => {
this.setState({
[e.target.email]: e.target.value,
[e.target.password]: e.target.value
});
};
onSubmit = e => {
e.preventDefault();
const { email, password } = this.state;
const user = {
email,
password
};
this.props.signin(user);
/* this.props.push('/dashboard'); */
};
render() {
return (
<>
<TopCont>
<div className="signin-cont">
<h1>Accedi</h1>
{this.state.msg ? <Alert color="danger">{this.state.msg}</Alert> : null }
<Form className="signin-form-cont" onSubmit={this.onSubmit}>
<FormGroup>
<Input className="signin-form" type="email" name="email" id="email" placeholder="mario.rossi#prova.it" onChange={this.onChange}/>
</FormGroup>
<FormGroup>
<Input className="signin-form" type="password" name="password" id="password" placeholder="Password" onChange={this.onChange}/>
</FormGroup>
<Button className="sign-btn">Accedi</Button>
</Form>
<p>Non hai ancora un account? <Link to="/signup">Registrati</Link></p>
</div>
</TopCont>
</>
)
}
}
const mapStateToProps = state => ({
isAuth: state.auth.isAuth,
err: state.err
});
export default connect(mapStateToProps, { signin, clearErrors })(Signin);
Here is my Action:
import axios from 'axios';
import { returnErrors } from './errAction';
import { AUTH_ERROR, LOGIN_FAIL } from '../actions/types';
export const signin = ({ email, password }) => dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ email, password });
axios.post('/api/auth', body, config)
.then(res => dispatch({
type: LOGIN_SUCCESS,
payload: res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'LOGIN_FAIL'));
dispatch({
type: LOGIN_FAIL
});
});
};
And here is my Auth API:
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const config = require('config');
const jwt = require('jsonwebtoken');
const auth = require('../../middleware/auth');
const User = require('../../models/User');
//#action POST api/auth
//#descr auth user
//#access Public
router.post('/', (req, res) => {
const { email, password } = req.body
if( !email || !password ) {
return res.status(400).json({ msg: "Enter all fields."});
}
User.findOne({ email })
.then(user => {
if(!user) return res.status(400).json({ msg: "Nessun profilo trovato con questa email"});
bcrypt.compare( password, user.password )
.then(isMatch => {
if(!isMatch) return res.status(400).json({ msg: "Password errata!"});
jwt.sign(
{ id: user.id },
config.get('jwtSecret'),
{ expiresIn: 10800 },
(err, token) => {
if(err) throw err;
res.json({
token,
user: {
id: user.id,
name: user.name,
surname: user.surname,
email: user.email,
userPlus: user.userPlus
}
})
}
)
})
})
});
//#action GET api/auth/user
//#descr GET user data
//#access Private
router.get('/user', auth, (req, res) => {
User.findById(req.user.id)
.select('-password')
.then(user => res.json(user));
});
module.exports = router;
If I try to get rid of all the errors controls my server return this error:
TypeError: Cannot read property 'password' of null
The strange thing is that if I try to register a new user (with an almost identical component and server-side method) there are no problems and it authenticates too with no problems.
Someone knows how can I fix this issue?
Change your onChange Function from this:
onChange = e => {
this.setState({
[e.target.email]: e.target.value,
[e.target.password]: e.target.value
});
};
to this:
onChange = e => this.setState(prevState => ({
...prevState,
[e.target.name]: e.target.value,
}));
I am trying to make user login page with react and redux.
//loginAction.js
export function loginRequest(user){
return{
type: types.LOGIN_REQUEST,
user
}
}
export function loginSuccess(user){
return{
type: types.LOGIN_SUCCESS,
user
}
}
export function loginFailure(err){
return{
type: types.LOGIN_FAILURE,
err
}
}
export function login(username, password){
return function(dispatch) {
dispatch(loginRequest({ username }));
userApi.userLogin(username, password)
.then(
user => {
dispatch(loginSuccess(user));
},
err => {
dispatch(loginFailure(err.toString()))
}
)
}
}
//userReducer.js
const login = (state=initialState, action) => {
switch(action.types){
case types.LOGIN_SUCCESS:
case types.LOGIN_REQUEST:
return {
loggedIn: true,
user: action.user
}
case types.LOGIN_FAILURE:
return {}
default:
return state
}
};
LoginPage.js
import React, { useState, useEffect} from 'react';
import PropTypes from 'prop-types';
import {useDispatch, useSelector} from 'react-redux';
import {Redirect} from 'react-router-dom';
import {login} from '../redux/actions/loginAction'
const LoginPage = () => {
const [inputs, setInputs] = useState({
username: '',
password: ''
})
const [isauthenticated, setIsAuthenticated] = useState(false);
const { username, password } = inputs
const dispatch = useDispatch();
const loggingIn = useSelector(state => state.user);
const handleChange = (e) => {
const {name, value} = e.target;
setInputs(inputs =>({...inputs, [name]: value}))
}
const handleSubmit = (event) => {
event.preventDefault();
// setIsAuthenticated(true)
// this line needs to be improved
if( username && password ){
dispatch(login(username, password))
}
}
return(
<div className='field col-xs-5 col-lg-3'>
{
isAuthenticated ?
<Redirect to='/uploadfile' /> :
(
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={handleChange}
name="username"
label="username"
className="form-control"
placeholder="ID"
value={username}
/>
<input
type="password"
onChange={handleChange}
name="password"
label="password"
className="form-control"
placeholder="Password"
/>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
)
}
</div>
)
}
export default LoginPage;
Inside of LoginPage component, I have isAuthenticated state that I want to set true when its action returns 'LOGIN_SUCCESS', not always set true.
Is there a way to check it, like this?
const handleSubmit = (event) => {
event.preventDefault();
// setIsAuthenticated(true)
if( username && password ){
// can I do?
if(dispatch(login(username, password)) === 'types.LOGIN_SUCCESS'){
setIsAuthticated(true)
}
}
}
const login = (state=initialState, action) => {
switch(action.types){
case types.LOGIN_REQUEST:
return {
loggedIn: false,
user: null
}
case types.LOGIN_SUCCESS:
return {
loggedIn: true,
user: action.user
}
case types.LOGIN_FAILURE:
return {
loggedIn: false,
user: null
}
default:
return state
}
};
I would write it like that, you're not logged in before login_success. And inside loginform you should only check props - loggedIn and user.
This one particular firebase function hasn't worked for me when calling it as an action. Login, edit username, register, all of those work fine... except logout.
After looking at some tutorials and Google's own documentation, I thought this function would work like all the other firebase-auth functions I've implemented.
Here's what my actions to the db look like:
/* AuthUser.js */
export const login = credentials => {
return (dispatch, getState, { getFirebase }) => {
const firebase = getFirebase();
firebase
.auth()
.signInWithEmailAndPassword(credentials.email, credentials.password)
.then(() => {
dispatch({ type: LOGIN_SUCCESS });
dispatch(push('/home'));
})
.catch(err => {
dispatch({ type: LOGIN_FAIL, err });
});
};
};
export const logout = () => {
return (dispatch, getState, { getFirebase }) => {
const firebase = getFirebase();
firebase
.auth()
.signOut()
.then(() => {
dispatch({ type: LOGOUT_SUCCESS });
dispatch(push('/login'));
}) /* ERROR POINTS RIGHT AT THIS LINE */
.error(err => {
dispatch({ type: LOGOUT_FAIL, err });
});
};
};
export const register = user => {
return (dispatch, getState, { getFirebase }) => {
const firebase = getFirebase();
firebase
.auth()
.createUserWithEmailAndPassword(user.email, user.password)
.then(res => {
return res.user.updateProfile({
displayName: user.displayName,
});
})
.then(() => {
dispatch({ type: REGISTER_SUCCESS });
dispatch(push('/login'));
})
.catch(err => {
dispatch({ type: REGISTER_FAIL, err });
});
};
};
export const save = displayName => {
return (dispatch, getState, { getFirebase }) => {
const firebase = getFirebase();
const user = firebase.auth().currentUser;
if (displayName !== '') {
user
.updateProfile({
displayName,
})
.then(() => {
dispatch({ type: SETTINGS_NAME_CHANGED });
dispatch(push('/home'));
})
.catch(err => {
dispatch({ type: SETTINGS_ERROR, err });
});
} else {
dispatch({ type: SETTINGS_LEFT_ALONE });
dispatch(push('/home'));
}
};
};
Here is how I'm setting up my connects in the Component that calls some of these functions.
/* Settings.js */
import React from 'react';
import { /* Some Stuff */ } from 'reactstrap';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import 'someStyles.scss';
import { logout, save } from '../store/actions/authUser';
class Settings extends React.Component {
constructor(props) {
super(props);
this.state = {
displayName: '',
};
}
/* This doesn't! */
onLogout = event => {
event.preventDefault();
this.props.logout();
};
/* This works! */
onSubmit = event => {
event.preventDefault();
this.props.save(this.state.displayName);
};
onChange = event => {
this.setState({
[event.target.id]: event.target.value,
});
};
render() {
const { displayName } = this.state;
return (
<Container className=".settingsBody">
<nav>
<Nav>
<NavItem>
<NavLink href="https://github.com">GitHub</NavLink>
</NavItem>
<NavItem>
<NavLink>
<div onClick={this.onLogout.bind(this)}>Logout</div>
</NavLink>
</NavItem>
</Nav>
</nav>
<Form onSubmit={this.onSubmit.bind(this)}>
<FormGroup>
<Label for="displayName">Change Display Name</Label>
<Input
type="text"
name="text"
id="displayName"
placeholder={this.props.auth.displayName}
value={displayName}
onChange={this.onChange}
/>
</FormGroup>
<Button color="primary">Save Settings</Button>
</Form>
</Container>
);
}
}
Settings.propTypes = {
logout: PropTypes.func.isRequired,
save: PropTypes.func.isRequired,
authError: PropTypes.string,
auth: PropTypes.object,
};
const mapStateToProps = state => {
return {
authError: state.auth.authError,
auth: state.firebase.auth,
};
};
const mapDispatchToProps = dispatch => {
return {
logout: () => dispatch(logout()),
save: displayName => dispatch(save(displayName)),
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Settings);
React throws this error: TypeError: firebase.auth(...).signOut(...).then(...).error is not a function Yet other functions run as expected when ran.
Is there something I'm missing? The code will attempt to navigate to the page I want but throws the error before that page properly mounts.
Promises doesn't have .error callback, it should be .catch.
Read about Using Promises
I was driven crazy by my first react-redux app. My Redux State is never updated.
I tried to find every solution on the website but they are not helping. One very similar question here used promise but I am not.
Redux-dev-tools catch the actions about the login_success but the global state is never updated, please tell me what should I do to debug if you could, thank you so much.
First Index.js
import ... from ...
const compostEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const rootReducer = combineReducers({
auth: authReducer,
})
const store = createStore(rootReducer, compostEnhancer(
applyMiddleware(thunk)
));
const app = (<BrowserRouter><App /></BrowserRouter>)
ReactDOM.render(<Provider store={store}>{app}</Provider>, document.getElementById('root'));
registerServiceWorker();
authReducer.js :
import * as actionTypes from '../actions/actionTypes';
const initialState = {
token: null,
userId: null,
error: null,
loading: false
}
const authReducer = (state = initialState, action) => {
switch (action.types) {
case actionTypes.LOGIN_START:
return {
...state,
};
case actionTypes.LOGIN_SUCCESS:
return {
...state,
token: action.idToken,
userId: action.userId,
loading: false,
error:null
}
default:
return state;
}
}
export default authReducer;
authAction.js:
import * as actionTypes from './actionTypes';
import axios from 'axios';
export const loginStart= () =>{
return {
type: actionTypes.LOGIN_START
};
}
export const loginSuccess = (token,userId) =>{
return {
type: actionTypes.LOGIN_SUCCESS,
userId: userId,
idtoken: token,
}
}
export const loginFail = (error) =>{
return {
type:actionTypes.LOGIN_FAIL,
error:error
}
}
export const auth = (email,password,isSignup ) =>{
return dispatch =>{
dispatch(loginStart());
const authData = {
email: email,
password: password,
returnSecureToken:true
}
let url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=...'
if(!isSignup ){
url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=...'
}
axios.post(url, authData)
.then( response =>{
console.log(response);
dispatch(loginSuccess(response.data.idToken, response.data.localId))
})
.catch(err=>{
console.log(err);
dispatch(loginFail(err));
})
}
}
Login.js (Component):
import ... from ...;
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
isSignup: false,
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit = e => {
e.preventDefault();
// This will trigger actions
this.props.onAuth(this.state.email, this.state.password, this.state.isSignup);
console.log(this.props.token) //here I can Get Token
}
handleChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
render() {
let form =
<div className={classes.ContactData} >
<h4>Sign IN</h4>
<form onSubmit={this.handleSubmit} >
<Input
elementType='input'
name="email"
required
label="Email"
placeholder="Email"
value={this.state.email}
margin="normal"
onChange={this.handleChange}
/>
<br />
<Input
elementType='input'
required
name="password"
value={this.state.password}
label="Password"
onChange={this.handleChange}
/>
<br />
<Button
color="primary"
type="submit"
>Submit</Button>
<Button color="primary" href="/"> CANCLE</Button>
</form>
</div>
if (this.props.loading) {
form = <Spinner />
}
let errorMessage = null;
if (this.props.error) {
errorMessage =(
<p>{this.props.error.message} </p>
)
}
let token = null;
if(this.props.token){
token = this.props.token.toString()
}
return (
<div>
{errorMessage}
{ form }
</div>
)
}
}
const mapStateToProps = state => {
return {
loading: state.auth.loading,
error: state.auth.error,
token:state.auth.idToken,
}
}
const mapDispatchToProps = dispatch => {
return {
onAuth: (email, password, isSignup) => dispatch(actions.auth(email, password, isSignup)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);
And also, the problem leads to my Spinner and show ErrorMessage not working.
I suppose its a typo.
instead of
switch (action.types)
try this
switch (action.type)
In reducer, we get an object returned from the actions, on the argument action.