如何使用纯 JavaScript 保持从 API 调用获取的响应中的顺序不变?

huangapple go评论60阅读模式
英文:

How to keep the order intact as it is in the response got from the API call using vanilla js?

问题

我正在尝试从API中获取产品列表,并传递升序降序排序的查询。单击下拉菜单中的desc后,我收到的响应是正确的,但页面应该列出元素的顺序却是错误的。

对于这个问题的任何帮助都将不胜感激。我已经附上了下面的图像作为问题的参考:

如何使用纯 JavaScript 保持从 API 调用获取的响应中的顺序不变?

我已经分享了下面的代码和一个**测试演示链接**供您参考。

const app = document.getElementById("app");
const table = document.createElement("table");
const loader = document.createElement("div");
const API_URL = `https://fakestoreapi.com`;
let ORDER = `asc`;
loader.innerHTML = `Loader..`;

function hideLoader() {
  app.removeChild(loader);
}

function showLoader() {
  app.appendChild(loader);
}

app.innerHTML = `
<h1>List</h1>
`;

const select = document.createElement("select");
const option1 = document.createElement("option");
const option2 = document.createElement("option");
option1.value = "asc";
option1.innerHTML = "asc";
option2.value = "desc";
option2.innerHTML = "desc";
select.appendChild(option1);
select.appendChild(option2);
app.appendChild(select);
select.addEventListener("change", (e) => handleChange(e));

function handleChange(e) {
  fetchData(e.target.value);
}

async function fetchData(order) {
  showLoader();
  const response = await fetch(`${API_URL}/products?sort=${order}`);
  const data = await response.json();
  displayData(data);
}

function displayData(data) {
  const tbody = document.createElement("tbody");
  console.log("data", data);
  data.forEach((item) => {
    const tr = document.createElement("tr");
    tr.key = item.id;
    tr.innerHTML = `
        <td>${item.id}</td>
        <td>${item.title}</td>
        <td>${item.price}</td>
    `;
    tbody.appendChild(tr);
  });
  table.appendChild(tbody);
  app.appendChild(table);
  hideLoader();
}

fetchData(ORDER);

<details>
<summary>英文:</summary>
I&#39;m trying to fetch the **list of products** from the API with passing the query for **ascending** and **descending orders**. After clicking **desc** from the dropdown, the response I&#39;m getting is correct but the order in which it should list out the elements in the page is getting wrong. 
Any help with the problem would be appreciated. I have attached the below image as a problem reference:
[![Output][1]][1]
I have shared the below code and a **[Test Demo Link][2]** for your reference.
const app = document.getElementById(&quot;app&quot;);
const table = document.createElement(&quot;table&quot;);
const loader = document.createElement(&quot;div&quot;);
const API_URL = `https://fakestoreapi.com`;
let ORDER = `asc`;
loader.innerHTML = `Loader..`;
function hideLoader() {
app.removeChild(loader);
}
function showLoader() {
app.appendChild(loader);
}
app.innerHTML = `
&lt;h1&gt;List&lt;/h1&gt;
`;
const select = document.createElement(&quot;select&quot;);
const option1 = document.createElement(&quot;option&quot;);
const option2 = document.createElement(&quot;option&quot;);
option1.value = &quot;aesc&quot;;
option1.innerHTML = &quot;aesc&quot;;
option2.value = &quot;desc&quot;;
option2.innerHTML = &quot;desc&quot;;
select.appendChild(option1);
select.appendChild(option2);
app.appendChild(select);
select.addEventListener(&quot;change&quot;, (e) =&gt; handleChange(e));
function handleChange(e) {
fetchData(e.target.value);
}
async function fetchData(order) {
showLoader();
const response = await fetch(`${API_URL}/products?sort=${order}`);
const data = await response.json();
displayData(data);
}
function displayData(data) {
const tbody = document.createElement(&quot;tbody&quot;);
console.log(&quot;data&quot;, data);
data.forEach((item) =&gt; {
const tr = document.createElement(&quot;tr&quot;);
tr.key = item.id;
tr.innerHTML = `
&lt;td&gt;${item.id}&lt;/td&gt;
&lt;td&gt;${item.title}&lt;/td&gt;
&lt;td&gt;${item.price}&lt;/td&gt;
`;
tbody.appendChild(tr);
});
table.appendChild(tbody);
app.appendChild(table);
hideLoader();
}
fetchData(ORDER);
[1]: https://i.stack.imgur.com/KdTGM.png
[2]: https://codesandbox.io/s/test-ordering-tlj4tf
</details>
# 答案1
**得分**: 1
问题在于每次调用API时都会添加一个新表格。
如果在添加产品之前移除任何现有的表格,问题将得到解决。
```javascript
// 如果存在,则移除表格并重新构建。
let tbody = document.getElementById("productTable");
if (tbody) {
tbody.remove();
}

完整的代码片段:

const app = document.getElementById("app");
const table = document.createElement("table");
const loader = document.createElement("div");
const API_URL = `https://fakestoreapi.com`;
let ORDER = `asc`;
loader.innerHTML = `Loader..`;

function hideLoader() {
  app.removeChild(loader);
}

function showLoader() {
  app.appendChild(loader);
}

app.innerHTML = `
<h1>List</h1>
`;

const select = document.createElement("select");
const option1 = document.createElement("option");
const option2 = document.createElement("option");
option1.value = "aesc";
option1.innerHTML = "aesc";
option2.value = "desc";
option2.innerHTML = "desc";
select.appendChild(option1);
select.appendChild(option2);
app.appendChild(select);
select.addEventListener("change", (e) => handleChange(e));

function handleChange(e) {
  fetchData(e.target.value);
}

async function fetchData(order) {
  showLoader();
  const response = await fetch(`${API_URL}/products?sort=${order}`);
  const data = await response.json();
  displayData(data);
}

function displayData(data) {
  // 如果存在,则移除表格并重新构建。
  let tbody = document.getElementById("productTable");
  if (tbody) {
    tbody.remove();
  }
  tbody = document.createElement("tbody");
  tbody.setAttribute("id", "productTable");

  console.log("data", data);
  data.forEach((item) => {
    const tr = document.createElement("tr");
    tr.key = item.id;
    tr.innerHTML = `
        <td>${item.id}</td>
        <td>${item.title}</td>
        <td>${item.price}</td>
    `;
    tbody.appendChild(tr);
  });
  table.appendChild(tbody);
  app.appendChild(table);
  hideLoader();
}

fetchData(ORDER);
<div id="app"></div>

希望这能帮助你解决问题。

英文:

The issue here is that a new table is added each time we call the API.

If we remove any existing table before adding the products, the issue will be resolved.

// Remove table and rebuild if it exists.
let tbody = document.getElementById(&quot;productTable&quot;);
if (tbody) {
tbody.remove();
}

Full code snippet:

<!-- begin snippet: js hide: false console: false babel: null -->
<!-- language: lang-js -->

const app = document.getElementById(&quot;app&quot;);
const table = document.createElement(&quot;table&quot;);
const loader = document.createElement(&quot;div&quot;);
const API_URL = `https://fakestoreapi.com`;
let ORDER = `asc`;
loader.innerHTML = `Loader..`;
function hideLoader() {
app.removeChild(loader);
}
function showLoader() {
app.appendChild(loader);
}
app.innerHTML = `
&lt;h1&gt;List&lt;/h1&gt;
`;
const select = document.createElement(&quot;select&quot;);
const option1 = document.createElement(&quot;option&quot;);
const option2 = document.createElement(&quot;option&quot;);
option1.value = &quot;aesc&quot;;
option1.innerHTML = &quot;aesc&quot;;
option2.value = &quot;desc&quot;;
option2.innerHTML = &quot;desc&quot;;
select.appendChild(option1);
select.appendChild(option2);
app.appendChild(select);
select.addEventListener(&quot;change&quot;, (e) =&gt; handleChange(e));
function handleChange(e) {
fetchData(e.target.value);
}
async function fetchData(order) {
showLoader();
const response = await fetch(`${API_URL}/products?sort=${order}`);
const data = await response.json();
displayData(data);
}
function displayData(data) {
// Remove table and rebuild if it exists.
let tbody = document.getElementById(&quot;productTable&quot;);
if (tbody) {
tbody.remove();
}
tbody = document.createElement(&quot;tbody&quot;);
tbody.setAttribute(&quot;id&quot;, &quot;productTable&quot;);
console.log(&quot;data&quot;, data);
data.forEach((item) =&gt; {
const tr = document.createElement(&quot;tr&quot;);
tr.key = item.id;
tr.innerHTML = `
&lt;td&gt;${item.id}&lt;/td&gt;
&lt;td&gt;${item.title}&lt;/td&gt;
&lt;td&gt;${item.price}&lt;/td&gt;
`;
tbody.appendChild(tr);
});
table.appendChild(tbody);
app.appendChild(table);
hideLoader();
}
fetchData(ORDER);

<!-- language: lang-html -->
<div id="app"></div>
<!-- end snippet -->

答案2

得分: 1

你提到你得到的响应是正确的,但数据的呈现顺序错误。

但那是错误的。新的(降序)数据被添加到当前表格中。根据你提供的测试演示链接。

你需要做的是移除当前表格中的数据,而不是添加到它。

尝试这样做:

function displayData(data) {
  let tbody = document.getElementsByTagName("tbody")?.item(0);

  if (!tbody) {
    tbody = document.createElement("tbody");
  }
  if (tbody) {
    tbody.innerHTML = "";
  }
  ...

它会检查表格主体是否存在,如果不存在,就会创建一个。否则,表格数据会被清除,以准备接收新的数据。

英文:

You stated that the response you were getting was correct, but that the data was being rendering in the wrong order.

But that is wrong. The new (descending) data was being added onto the current table. As per the Test Demo Link you provided.

What you need to do is to remove the data in the current table, instead of added onto it.

Try this:

function displayData(data) {
let tbody = document.getElementsByTagName(&quot;tbody&quot;)?.item(0);
if (!tbody) {
tbody = document.createElement(&quot;tbody&quot;);
}
if (tbody) {
tbody.innerHTML = &quot;&quot;;
}
...

It is checking it the table body exists, if it doesn't, it is created. Otherwise it table data is cleaned to prepare it for the new data.

huangapple
  • 本文由 发表于 2023年6月19日 14:41:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76504184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定