简体   繁体   中英

How to avoid making a fetch() request every time you do something like sort, filter, etc. some JSON data in vanilla JavaScript?

When the page loads it brings data to the page good:

fetch("theData.json")
  .then(function (response) {
    return response.json();
  })
  .then(function (objArray) {
    mainFunctionThatPresentsTheData(objArray);
  });

But then I have multiple buttons that do sorting, for example lowest to highest price, highest to lowest based on some attribute of the json objects in the JSON Array, etc.

I managed to successfully perform this functionality, however, I don't think it's really efficient because I make a new fetch() request every time I click a "sort" button:

function customSort(sortOrder, byWhatAttribute) {
  output.innerHTML = "";
  fetch("theData.json")
    .then(function (response) {
      return response.json();
    })
    .then(function (objArray) {
      for (let i = 0; i < obj.length; i++) {
        objArray[i].somethingInTheJsonObjArrayThatIWantToSort.sort(sortOrder(byWhatAttribute));   
      }
      mainFunctionThatPresentsTheData(objArray);
    });
}

I tried this:

let globalEmptyArray; //<----- addition 1
//this gets called when the page loads or gets refreshed
fetch("theData.json")
  .then(function (response) {
    return response.json();
  })
  .then(function (objArray) {
  globalEmptyArray = objArray; //<----- addition 2
    mainFunctionThatPresentsTheData(objArray);
  });

function customSort(sortOrder, byWhatAttribute) {
  output.innerHTML = "";
  // addition 3 ... the globalEmptyArray is not supposed to be empty anymore.
  for (let i = 0; i < globalEmptyArray.length; i++) {
    globalEmptyArray[i].somethingInTheJsonObjArrayThatIWantToSort.sort(sortOrder(byWhatAttribute));
    
  }

  mainFunctionThatPresentsTheData(globalEmptyArray);
}

The customSort() function gets called like this:

sortBySomethingAscendingButton.addEventListener("click", () => {
  customSort(sortAscendingBy, "someAttribute");
});

This actually does work but the problem is that it only works once, like, when I do "sortDescendingBy":

sortBySomethingDescendingButton.addEventListener("click", () => {
  customSort(sortDescendingBy, "someAttribute");
});

It gives the same result as customSort(sortAscendingBy, "someAttribute")... like the data is "stuck" in ascending order just because I clicked the ascending button once, and I know that both the ascending and descending buttons each work because they work perfectly when calling the fetch() request every time... I just thought that the global array will just capture the data from the initial fetch() request.

JSON looks like this:

[   {
    "A": "A's value",
    "BList": [
      {
        "C": 1,
        "D": 2,
        "E": 3
      },
      {
        "C": 5,
        "D": 6,
        "E": 7
      }
    ]
      }
]

Sort functions look like this, these are the arguments passed as the sortOrder "callback function" parameter:

export function sortDescendingBy(prop) {
  return function (a, b) {
    
    if (a[prop] > b[prop]) return -1;
  };
}
export function sortAsendingBy(prop) {
  return function (a, b) {
    
    if (a[prop] > b[prop]) return 1;
  };
}

There is a problem with your sorting functions. When you want to sort an array, you should return 1 or -1.

Currently you only return one of them and the other value is undefined.

Use this code:

export function sortDescendingBy(prop) {
  return function (a, b) {
    if (a[prop] > b[prop]) {
      return -1;
    } else {
      return 1;
    }
  };
}
export function sortAsendingBy(prop) {
  return function (a, b) {
    if (a[prop] > b[prop]) {
      return 1;
    } else {
      return -1;
    }
  };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM