0

I am trying to get some statistics and problems for a user using a Redux action and pass it to a React component. The problem is, I have the array of objects curPageExercisesMarked, which I use for the pagination of the page, but it does not take the values I assign it to.

The stranger thing is that the other fields in the Redux store get updated, but not this one. I tried consoling the object in the action, but it just prints this: Array of object in console

It is important to mention that I am doing something similar in another action, using the exact same assignment and it works there. I've lost already an hour trying to figure this thing out so any help is welcomed.

The Redux action:

export const setStatistics = (
problems,
problemsSolved,
filter = ''
) => dispatch => {
let payload = {
subject1: 0,
subject2: 0,
subject3: 0,
total: 0,
exercisesMarked: [],
curPageExercisesMarked: []
};
for (let i = 0; i < problems.length; i++) {
  if (problems[i].S === '1' && problemsSolved.includes(problems[i]._id)) {
   payload.subject1++;
   payload.total++;
   payload.exercisesMarked.push(problems[i]);
  } else if (
   problems[i].S === '2' &&
   problemsSolved.includes(problems[i]._id)
  ) {
   payload.subject2++;
   payload.total++;
   payload.exercisesMarked.push(problems[i]);
  } else if (
   problems[i].S === '3' &&
   problemsSolved.includes(problems[i]._id)
  ) {
   payload.subject3++;
   payload.total++;
   payload.exercisesMarked.push(problems[i]);
  }
 }

 payload.curPageExercisesMarked = payload.exercisesMarked.slice(0, 10);

 dispatch({
  type: SET_USER_STATISTICS,
  payload
 });
};

The redux reducer:

export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case SET_USER_STATISTICS:
  return {
    ...state,
    exercisesMarked: payload.exercisesMarked,
    curPageExercisesMarked: payload.curPageExercisesMarked,
    subject1: payload.subject1,
    subject2: payload.subject2,
    subject3: payload.subject3,
    total: payload.total
  };
 case CHANGE_PAGE_MARKED:
  return {
    ...state,
    page: payload,
    curPageExercisesMarked: state.exercisesMarked.slice(
      (payload - 1) * state.pages_count,
      payload * state.pages_count
    )
  };
 default:
  return state;
 }
}

This is the part that does not function: payload.curPageExercisesMarked = payload.exercisesMarked.slice(0, 10);

EDIT

I've discovered that if I go a component which loads all the problems and come back to this component, it actually gets the correct value. Now, the interesting is that I do get the same problems here as well. Is it the way I use React Hook?

This is the part where I call the redux action in the react component:

const Dashboard = ({
problems: { problems },
auth: { user },
getProblems,
dashboard: {
curPageExercisesMarked,
page,
exercisesMarked,
pages_count,
subject1,
subject2,
subject3,
total
},
setStatistics
}) => {
useEffect(() => {
 if (problems === null) {
   getProblems();
 } else if (user !== null) {
   setStatistics(problems, user.problemsSolved);
 }
}, [problems, user]);
// rest of the code
}
9
  • can you console log "payload.exercisesMarked.slice(0, 10);" this part and see if this is even getting data you are expecting to assign it to other one Commented Mar 23, 2020 at 18:42
  • Yes, it does get what it should get. It looks like this: [{..}] -> 0: {help1: Array(1), help2:Array(1), ...(rest of object) -> 1:... ... So it does get what it should get Commented Mar 23, 2020 at 18:45
  • can you console log "payload.curPageExercisesMarked" inside reducer case and see if it is there Commented Mar 23, 2020 at 18:48
  • It is the same as in the picture from the post. The thing is, I tried updating payload.curPageExercisesMarked with push in a for, but the same thing happens. It doesn't even add one object to the array Commented Mar 23, 2020 at 18:52
  • 1
    check where ever you dispatch "CHANGE_PAGE_MARKED" I would start there and see if you need to dispatch both actions at same time, and see if this "state.exercisesMarked" has data in it in that case, if so then check your slice because use of payload - 1 doesnt make sense to me Commented Mar 23, 2020 at 19:20

1 Answer 1

1

You can first simplify code as below. Update/Print console.log(JSON.stringify(payload)). I think if(problemsSolved.includes(problems[i]._id)) not working as expected

export const setStatistics = (
  problems,
  problemsSolved,
  filter = ""
) => dispatch => {
  let payload = {
    subject1: 0,
    subject2: 0,
    subject3: 0,
    total: 0,
    exercisesMarked: [],
    curPageExercisesMarked: []
  };
  for (let i = 0; i < problems.length; i++) {
    if(problemsSolved.includes(problems[i]._id)) {
      payload["subject"+ problems[i].S]++
      payload.total++;
      payload.exercisesMarked.push(problems[i]);
    }
  }
  payload.curPageExercisesMarked = payload.exercisesMarked.slice(0, 10);

  dispatch({
    type: SET_USER_STATISTICS,
    payload
  });
};

// Also

case SET_USER_STATISTICS:
  return {
    ...state,
    ...payload
  };
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you! i am new to the way you can simplify things in JavaScript. Also, I did print my payload in the way you mentioned and, strangely, here it has the value it needs
You know, even the render renders it for a split second, then it disappears
Meaning, it retriggers this function and that time data is blank. Somethig async is causing issue. Dont mix side-effect with sync code.
But if I log the variables, nothing is empty/ undefined / null
yeah! coz default value is let payload = { subject1: 0, subject2: 0, subject3: 0, total: 0, exercisesMarked: [], curPageExercisesMarked: [] };
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.