1

So I'm trying to sort the column by clicking on the header and it causes much damage. I guess it's an infinite loop :)

Though, same logic works fine while it was array of arrays, not objects. It's all in redux reducer.

Where is my bug?

const newData = an array of objects.

newData[0] - {
               show: true,
               value: [5, 3, "quidem molestiae enim"]
             }

newData[0].value - it's a table row with td.

const sortDataFunc = (state, action) => {
        const newData = [].concat(action.data);
        index = action.columnIndex;
        let i, x, y, shouldSwitch, switchcount = 0;
        let switching = true;
        let dir = "asc"; 

        /* Make a loop that will continue until
        no switching has been done: */
        while (switching) {
          switching = false;
          for (i = 0; i < (newData.length - 1); i++) {
            // Start by saying there should be no switching:
            shouldSwitch = false;
            /* Get the two elements you want to compare,
            one from current row and one from the next: */
            x = newData[i].value[index];
            y = newData[i + 1].value[index];  

            /* Check if the two rows should switch place,
            based on the direction, asc or desc: */
            if (dir === "asc") {
              if (x > y) {
                // If so, mark as a switch and break the loop:
                shouldSwitch = true;
                break;
              }
            } else if (dir === "desc") {
              if (x < y) {
                // If so, mark as a switch and break the loop:
                shouldSwitch = true;
                break;
              }
            }
          }
          if (shouldSwitch) {
            /* If a switch has been marked, make the switch
            and mark that a switch has been done: */
            const newRow = newData[i + 1];
            const copyObj = Object.assign({}, newRow);
            newData.splice(i + 1, 1);
            newData.splice(i, 0, copyObj);
            switching = true;
            switchcount ++;
          } else {
            /* If no switching has been done AND the direction is "asc",
            set the direction to "desc" and run the while loop again. */
            if (switchcount === 0 && dir === "asc") {
              dir = "desc";
              switching = true;
            }
          }
        } 
        return {
            ...state,
            dataToTable: newData
        }
};
1
  • Problem is your switching variable is never going to be false because you are assigning true in both if/else block of shouldSwitch. Commented Apr 30, 2019 at 7:09

1 Answer 1

2

try to use standard js sort and split data and view

let newData = [
  {show: true, value: [5, 1, "quidem molestiae enim"] },
  {show: true, value: [6, 3, "abc"] },
  {show: true, value: [7, 2, "zzz"] },
  {show: false, value: [8, 9, "not show"] },
];

let dir=[1,1,1] // sort direction

function sort(i) {
  if(i<2) newData = newData.sort((a,b)=> dir[i]*(a.value[i]-b.value[i]));
  if(i==2) newData= newData.sort((a,b)=> dir[i]*(a.value[i]<b.value[i]?-1:1));
  dir[i]*=-1
  show();
}

function show() {
  content.innerHTML = newData.map(d=> d.show ? '<tr>'+d.value.map(x=>`<td>${x}</td>`).join('')+'</tr>' : '').join('');
}

show();
thead td { cursor: pointer; border-bottom: 1px solid black; padding: 0 10px 3px 10px}
<div>(click on column name to sort)<br><br></div>
<table >
<thead><tr>
  <td onclick='sort(0)'>ID</td>
  <td onclick='sort(1)'>Age</td>
  <td onclick='sort(2)'>Text</td>
</tr></thead>
<tbody id='content'></tbody>
</table>

Sign up to request clarification or add additional context in comments.

Comments

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.