Why am i still getting cannot read map of undefined? - javascript

Running redux sagas and react together and totally stumped why i'm still getting undefined errors. I have an initial state set so that .map can just run on that, i've tried null, undefined, empty arrays - always the same error.
Where am I going wrong, guys & gals?
App.js
{
isFetching ? (
<button disabled>Fetching...</button>
)
:
<div>
<button onClick={onRequest}>Click For API Names</button>
<ul>
{users.map((each, i) => <li key={i}>{each.name}</li>)}
</ul>
</div>
};
...
const mapStateToProps = state => {
return {
isFetching: state.isFetching,
users: state.users,
error: state.error,
};
};
const mapDispatchToProps = dispatch => {
return {
onRequest: () => dispatch({ type: constants.API_REQUEST }),
};
};
reducer.js
const initialState = {
isFetching: false,
users: [{ name: '' }, { name: '' }],
error: null,
};
export const namesReducer = (state = initialState, action) => {
switch(action.type) {
case constants.API_REQUEST:
return {
...state,
isFetching: true,
error: null,
};
case constants.API_SUCCESS:
return {
...state,
isFetching: false,
users: action.payload,
error: null,
};
case constants.API_FAILURE:
return {
...state,
isFetching: false,
users: [''],
error: action.error,
};
default:
return state;
};
}

users: action.payload
action payload probably isn't an array

Related

why the profile inside the state return null instead of empty object after update?

I have a problem with my redux reducer.It doesn't return the expected state after dispatching the getCurrentProfile action, it returns the initial state which is "null" instead of "{}", which is fetched with an ajax request, so when the network return the result the state profile change to the result returned but when it is an error returned it stay null instead of empty object, so that is my code:
enter image description here
profileAcction.js :
import axios from 'axios';
import { GET_PROFILE, PROFILE_LOADING, CLEAR_CURRENT_PROFILE} from './types';
//Loading profile
const setProfileLoading = () => {
return {
type: PROFILE_LOADING
}
};
// Clear current profile
export const clearCurrentProfile = () => {
return {
type: CLEAR_CURRENT_PROFILE,
}
}
// Get current profile
export const getCurrentProfile = () => dispatch => {
dispatch(setProfileLoading());
axios.get('/api/profile')
.then(res => dispatch({
type: GET_PROFILE,
payload: res.data
})).catch(error =>
dispatch({
type: GET_PROFILE,
payload: {}
}))
};
profileReducer.js:
import {GET_PROFILE, PROFILE_LOADING, CLEAR_CURRENT_PROFILE} from '../actions/types';
const initialState = {
profile: null,
profiles: null,
loading: false
};
const profileReducer = (state=initialState, action) => {
switch(action.type) {
case PROFILE_LOADING:
return {
...state,
loading: true
}
case GET_PROFILE:
return {
...state,
profile: action.payload,
loading: false
}
case CLEAR_CURRENT_PROFILE:
return {
...state,
profile: null,
loading: false
}
default:
return state;
}
};
export default profileReducer;

User Auth with React Context API

I'm using React, Axios and Mongoose. Trying to store a user state but am having trouble with the stored state.user object.
When I manually enter values for state.user, the app works properly, however when I actually login from the site, the user object is stored in localStorage but is not being read properly by the app. I noticed I had to remove new ObjectId from the object and also convert the createdAt and lastUpdated dates into strings in order for my static values to work. How can I get around this? Thanks!
Screenshot of localStorage object
context.js
const INITIAL_STATE = {
user: JSON.parse(localStorage.getItem("user")) || null,
isFetching: false,
error: false,
};
export const AuthContext = createContext(INITIAL_STATE);
export const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE);
useEffect(() => {
JSON.stringify(localStorage.setItem("user", state.user));
}, [state.user]);
return (
<AuthContext.Provider
value={{
user: state.user,
isFetching: state.isFetching,
error: state.error,
dispatch,
}}
>
{children}
</AuthContext.Provider>
);
};
reducer.js
const AuthReducer = (state, action) => {
switch (action.type) {
case "LOGIN_START":
return {
user: null,
isFetching: true,
error: false,
};
case "LOGIN_SUCCESS":
return {
user: action.payload,
isFetching: false,
error: false,
};
case "LOGIN_FAILURE":
return {
user: null,
isFetching: false,
error: true,
};
case "FOLLOW":
return {
...state,
user: {
...state.user,
following: [...state.user.following, action.payload],
},
};
case "UNFOLLOW":
return {
...state,
user: {
...state.user,
following: state.user.following.filter(
(following) => following !== action.payload
),
},
};
default:
return state;
}
};
export default AuthReducer;
actions.js
export const LoginStart = (userCredentials) => ({
type: "LOGIN_START",
});
export const LoginSuccess = (user) => ({
type: "LOGIN_SUCCESS",
payload: user,
});
export const LoginFailure = (error) => ({
type: "LOGIN_FAILURE",
payload: error,
});
export const Follow = (userId) => ({
type: "FOLLOW",
payload: userId,
});
export const Unfollow = (userId) => ({
type: "UNFOLLOW",
payload: userId,
});
utils/api.js
import axios from "axios";
export const loginCall = async (userCredentials, dispatch) => {
dispatch({ type: "LOGIN_START" });
try {
const response = await axios.post("/api/auth/login", userCredentials);
dispatch({ type: "LOGIN_SUCCESS", payload: response.data });
} catch (error) {
dispatch({ type: "LOGIN_FAILURE", payload: error });
}
};

Pervious state is removed when I update state in react native redux

I call get_user_profile_api inside the app after login. On successful login my app has user and token in the state. But as soon as GET_USER_PROFILE_SUCCESS is called, the state is left only with userData and isLoading. user and token are removed from the state.
import { CONST } from '../../utils/Const';
import * as types from './types';
const initialState = {
isLoading: false,
user: null,
userData: null,
isLoggedIn: false,
token: '',
};
export default authReducer = (state = initialState, action) => {
console.log('action :: ', action);
switch (action.type) {
case types.GET_USER_PROFILE_LOADING:
case types.LOGIN_LOADING:
return {
isLoading: true,
};
case types.GET_USER_PROFILE_SUCCESS:
return {
...state,
isLoading: false,
userData: action.payload,
};
case types.LOGIN_SUCCESS:
return {
...state,
isLoading: false,
isLoggedIn: true,
user: action.payload.user,
token: action.payload.token,
};
case types.LOGIN_ERROR:
case types.GET_USER_PROFILE_ERROR:
return {
...state,
isLoading: false,
};
default:
return {
...state,
isLoading: false,
};
}
};
there is nothing wrong with this code I think the issue is where you are calling these actions from and you can call them inside a use-effect hook to get a user profile if there is a token or maybe you are not mapping state to props correctly
I was not writing ...state in the LOADING case. That's why my state was being removed.

React Redux reducer not Updating State

So I have a reducer which doesn't seem to be updating the state at all whenever I called the 'LOGIN' action. It could be a problem with my React Redux code. It's either my component is not getting re rendered whenever the store's state changes or the reducer is not changing the stores state at all.
Reducer ------
const initialState = {
messages: [],
loginDetails: {
email: '',
password: ''
},
activeUsers: [],
loginActive: false
}
const messageReducer = (state = initialState, action) => {
switch(action.type) {
case 'ADD_MESSAGE':
if(state.messages.length < 50) {
let newStateMessages = [...state.messages]
newStateMessages.unshift(action.payload);
console.log(newStateMessages);
return {...state, messages: newStateMessages};
} else {
let newStateMessages = [...state.messages]
newStateMessages.pop();
newStateMessages.unshift(action.payload);
return {...state, newStateMessages};
}
case 'LOGIN':
console.log('LOGIN');
console.log(action);
const newLoginDetails = {
email: action.payload.email,
password: action.payload.password
};
console.log({...state, loginDetails: newLoginDetails});
return {...state, loginDetails: newLoginDetails};
case 'UPDATE_USERS':
const newActiveUsers = action.payload;
return {...state, activeUsers: newActiveUsers};
case 'LOGIN_ACTIVE':
return {...state, loginActive: true};
case 'LOGIN_EXIT':
return {...state, loginActive: false};
default:
return state;
}
}
export const store = createStore(messageReducer);
React Redux connect -----
const mapStateToProps = state => {
return { ...state }
}
export default connect(mapStateToProps)(Home);
This mapStateToProps returns...
{
activeUsers: []
dispatch: ƒ dispatch(action)
loginActive: true
loginDetails: {email: "", password: ""}
messages: []
__proto__: Object
}
when it should return...
{
activeUsers: []
loginActive: true
loginDetails: {email: "example#gmail.com", password:
"password"}
messages: []
__proto__: Object
}
I have tested for sure that the dispatch to the reducer is getting called, and the payload is correct. However, the reducer is failing to update the state with the LOGIN action type.
Can you try this:
const mapStateToProps = ({activeUsers,loginActive,loginDetails,messages}) => ({
activeUsers,
loginActive,
loginDetails,
messages
})

Redux data undefined

In logger seen anything is normal data loaded successfully.
You can see it by follow this link https://i.stack.imgur.com/uTLpr.jpg
But why this crypto props is undefined and how to fix it.
Does anyone have any idea?
Component
class CryptoContainer extends Component {
componentWillMount(){
this.props.Fetchcoin()
}
renderCoinCards() {
const { crypto } = this.props;
console.log('Crypto : '+crypto)
return crypto.data.map((coin,index) => //Add this
<CoinCard
key={coin.name}
coin_name={coin.name}
symbol={coin.symbol}
price_usd={coin.price_usd}
percent_change_24h={coin.percent_change_24h}
percent_change_7d={coin.percent_change_7d}
/>
)
}
}
function mapStatetoProps(state){
return{
crypto:state.crypto
}
}
export default connect(mapStatetoProps,{Fetchcoin})(CryptoContainer)
>
Action
export default function FetchCoin(){
return dispatch => {
dispatch({type:FETCHING_COIN_DATA})
return axios.get(`https://api.coinmarketcap.com//v1/ticker/?limit=10`)
.then(res => {
dispatch({type:FETCHING_COIN_DATA_SUCCESS,payload:res.data})
})
.catch(err => {
dispatch({type:FETCHING_COIN_DATA_FAIL,payload:err.data})
})
}
}
Reducer
const initialState = {
isFetching: null,
data: [],
hasError: false,
errorMessage: null
}
export default function (state = initialState, action) {
switch (action.type) {
case FETCHING_COIN_DATA:
return Object.assign({}, state, {
isFetching: true,
data: null,
hasError: false,
errorMessage: null
})
case FETCHING_COIN_DATA_SUCCESS:
return Object.assign({}, state, {
isFetching: false,
data: action.payload,
hasError: false,
errorMessage: null
})
case FETCHING_COIN_DATA_FAIL:
return Object.assign({}, state, {
isFetching: false,
data: action.payload,
hasError: true,
errorMessage: action.err
})
default:
return state
}
}
And store
const middleware = applyMiddleware(thunk,promise,logger)
const rootReducer = combineReducers({
crypto:CyptoReducer
})
const Store = createStore(
rootReducer,middleware
)
export default Store
I fixed misspelling in store but when I add crypto.data.map() in renderCoinCard
data seem still not working debugger shown
TypeError: Cannot read property 'map' of null
I think there is a problem with your declaration of rootReducer.Here you have mentioned "cypto" instead of "crypto". Fix this and it will work as here only redux declares a reducer and as you have declared here as "cypto" it expects "cypto" and fails.

Categories

Resources