2

I am Fetching the data from Server and I am having two Objects with "name" and "Money" in the array Now I need to sort the array by comparing with money field, After trying with below code I am getting error like "TypeError: Cannot read property 'money' of undefined" , somewhere I facing problem with If condition,

const [dataObject, setdataObject] = useState([{}])

  const sortbyRich=()=>{
       
         for(let i=0;i<dataObject.length;i++){
           for(let j=0;j<dataObject.length;j++){
              if(dataObject[j].money < dataObject[j+1].money){
                
                    let temp = dataObject[j];
                    dataObject[j]= dataObject[j+1];
                    dataObject[j+1]= temp;
              }  
           }
         }
       setdataObject(dataObject);
   }
3
  • Does this answer your question? Sorting an array of objects by property values Commented Oct 13, 2020 at 5:25
  • Firstly, you are mutating the state. NEVER mutate state in React. Secondly, if your loop reaches the last element in the array, then this code dataObject[j+1].money will look for the next one, but since there's no next one then dataObject[j+1] will be undefined, and you'll get that error. Check if you're at the last element before trying to access the next one Commented Oct 13, 2020 at 5:26
  • Or just const sortByRich = () => setdataObject(prevData => prevData.slice().sort((a, b) => b.money - a.money)); Commented Oct 13, 2020 at 5:28

2 Answers 2

4

The issue is this line

if(dataObject[j].money < dataObject[j+1].money){

Your initial state is an array with only 1 element in it, so not only by definition is it already sorted, but accessing object properties past the last index j + 1 will yield an undefined access error.

Use a regular array::sort and pass your own comparator. Use a functional state update, copy the current array, sort in-place and return new sorted array.

Since comparing numbers:

setdataObject(data => {
  const dataToSort = [...data];
  dataToSort.sort((a, b) => Number(a.money) - Number(b.money)); // or b.money - a.money to invert order
  return dataToSort; // <-- now sorted ascending
})

Edit how-to-sort-the-the-array-in-react-hooks-using-usestate

const data = [
  {
    id: 0,
    money: '13.37'
  },
  {
    id: 1,
    money: '13.36'
  },
  {
    id: 2,
    money: '6.99'
  },
  {
    id: 3,
    money: '14'
  },
  {
    id: 4,
    money: '0.03'
  },
  {
    id: 5,
    money: '6.98'
  }
];

const App = () => {
  const [dataObject, setdataObject] = useState(data);

  const sortByRich = () => {
    setdataObject((data) => {
      const dataToSort = [...data];
      dataToSort.sort((a, b) => Number(a.money) - Number(b.money));
      return dataToSort;
    });
  };

  return (
    ...
  );
}
Sign up to request clarification or add additional context in comments.

4 Comments

Can you do this in Stackbiltz , Because when we return dataToSort it is giving me the original array data only not the sorted array data
@Sundeep that's a tall request considering you haven't provided a minimal reproducible example yourself.
Here a small mistake is we nee to change parseInt(b.money) - parseInt(a.money) then Its works for me
@Sundeep Sure. Updated answer to provide a running codesandbox.
2
// let's assume you are getting this array of object

let objArr = [
  {name: "Elon", money: 80},
  {name: "Jeff", money: 100},
  {name: "Bill", money: 10}
];

/*
Now just sort it.
For desc sort: objArr.sort((a,b) => parseInt(b.money) - parseInt(a.money))
For asc sort: objArr.sort((a,b) => parseInt(a.money) - parseInt(b.money))
*/
objArr.sort((a,b) => parseInt(b.money) - parseInt(a.money))

console.log(objArr);

/*
OUTPUT:
[
  { name: 'Jeff', money: 100 },
  { name: 'Elon', money: 80 },
  { name: 'Bill', money: 10 }
]

*/

// now use the hook to save sorted data

setObjectdata(objArr);

4 Comments

I am getting the sorted array data in console, But It is not updating the state in browser I did like this dataObject.sort((a,b) => b.money - a.money) console.log(dataObject); setdataObject(dataObject);
@Sundeep it's because sort() operates in place. As Drew correctly points out, you need to copy the current array before sorting it so that React will correctly update the state.
Yes it working thanks a lot, Your code solved my Issue
You would want to memoize the sorted start to avoid re-sorting on each render, only on array changes

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.