1

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);
   }
HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Sundeep
  • 169
  • 3
  • 17
  • Does this answer your question? [Sorting an array of objects by property values](https://stackoverflow.com/questions/979256/sorting-an-array-of-objects-by-property-values) – CertainPerformance Oct 13 '20 at 05: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 – Jayce444 Oct 13 '20 at 05:26
  • Or just `const sortByRich = () => setdataObject(prevData => prevData.slice().sort((a, b) => b.money - a.money));` – Patrick Roberts Oct 13 '20 at 05:28

2 Answers2

3

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 (
    ...
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
1
// 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);
Ketan Ramteke
  • 10,183
  • 2
  • 21
  • 41
  • 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 Oct 13 '20 at 05:48
  • @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. – Patrick Roberts Oct 13 '20 at 05:51
  • Yes it working thanks a lot, Your code solved my Issue – Sundeep Oct 13 '20 at 05:53
  • You would want to memoize the sorted start to avoid re-sorting on each render, only on array changes – Mordechai Oct 13 '20 at 06:00