Вставка информации из массива объектов со вложенным массивом объектов

Рейтинг: 0Ответов: 2Опубликовано: 20.01.2023

На основании ответа сервера мне нужно выводить на страницу некоторые элементы. Проблема в том, что ответ является массивом объектов со вложенным массивом объектов, и я не знаю, у меня не получается вот на втором уровне массива объектов вытаскивать необходимую информацию так, чтобы по итогу у меня не дублировались элементы при вставке в документ.

const resultsBlock = document.getElementById('results');

let resp = [{
  "_id": "63a0df907e9b89f949096c72",
  "pdf_file_id": "63a0df8f53baa85ee0096638",
  "title": "sample.pdf",
  "updated_at": "2022-12-19 22:02:57",
  "tags": [{
    "title": "1",
    "color": "purple",
    "updated_at": "2023-01-20 08:47:07",
    "created_at": "2023-01-20 08:47:07",
    "_id": "63ca550bdcc60c139b0eec5b"
  }, {
    "title": "8",
    "color": "red",
    "updated_at": "2023-01-20 08:48:09",
    "created_at": "2023-01-20 08:48:09",
    "_id": "63ca5549e8b09bcb6708dab3"
  }],
  "pdf_file": {
    "_id": "63a0df8f53baa85ee0096638",
    "images": {"small": "thumbnails\/5245c582a3f9981a642c32561ed906d2.png"}
  },
  "pdf_sharing": null,
  "link_to_sign": null,
  "link_to_fill": null
}, {
  "_id": "63b520654edf85b79002f992",
  "pdf_file_id": "63b52064b8be365fdd072c16",
  "title": "33557-001.pdf",
  "updated_at": "2023-01-11 07:46:03",
  "tags": [{
    "title": "3",
    "color": "grey",
    "updated_at": "2023-01-20 08:47:54",
    "created_at": "2023-01-20 08:47:54",
    "_id": "63ca553ae8b09bcb6708dab2"
  }, {
    "title": "5",
    "color": "yellow",
    "updated_at": "2023-01-20 08:47:59",
    "created_at": "2023-01-20 08:47:59",
    "_id": "63ca553f3363b2065f0cbe31"
  }],
  "pdf_file": {
    "_id": "63b52064b8be365fdd072c16",
    "images": {"small": "thumbnails\/0c4323c3c623563bd2ad016b86e9f2fc.png"}
  },
  "pdf_sharing": null,
  "link_to_sign": null,
  "link_to_fill": null
}]


/* перебор ответа сервера */
function responseIteration() {
  const responseData = resp.map(item => {
    const docID = item._id,
          docTitle = item.title;
    
    const innerValues = Object.values(item.tags);
    
    /* перебор для вложенного массива объектов с тегами */
    return innerValues.map(subItem => {
      const tagID = subItem._id,
            tagColor = subItem.color;
      
      /* разметка вставляемого документа */
      let documentMarkup = {
            'markup': `<div class="document-item" data-id="${docID}">
                  <a class="title">${docTitle}</a>
                  <ul class="tags-list">
                    <li><span class="item ${tagColor}"></span></li>
                  </ul>
                </div>`
      }
      
      /* непосредственно вставка */
      resultsBlock.insertAdjacentHTML('afterbegin', documentMarkup.markup);
    });
  });
}


responseIteration();
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.item {
  display: inline-flex;
  width: 15px;
  height: 15px;
}

.grey {
  background: #d3d3d3;
}
.yellow {
  background: yellow;
}
.purple {
  background: purple;
}
.red {
  background: red;
}
<div id="results"></div>

В моём коде я понимаю что ошибка в том, что insertAdjacentHTML выполняется уже при переборе tags, но если вынести его на уровень первого перебора, тогда информация из tags недоступна.

Песочница здесь.

Ответы

▲ 0Принят

Потому что Вам сначала необходимо перебрать тэги в эелементе, аккумулировать элементы списка, а потом вставлять в родительский элемент.

По коду заменил map на forEach, потому что вы ничего не возвращаете из map. А reduce просто для удобства, чтобы сразу строку вернуть. Хотя можете использовать map().join('') вместо этого. На алгоритм самой задачи не влияет.

const resultsBlock = document.getElementById('results');

let resp = [{
  "_id": "63a0df907e9b89f949096c72",
  "pdf_file_id": "63a0df8f53baa85ee0096638",
  "title": "sample.pdf",
  "updated_at": "2022-12-19 22:02:57",
  "tags": [{
    "title": "1",
    "color": "purple",
    "updated_at": "2023-01-20 08:47:07",
    "created_at": "2023-01-20 08:47:07",
    "_id": "63ca550bdcc60c139b0eec5b"
  }, {
    "title": "8",
    "color": "red",
    "updated_at": "2023-01-20 08:48:09",
    "created_at": "2023-01-20 08:48:09",
    "_id": "63ca5549e8b09bcb6708dab3"
  }],
  "pdf_file": {
    "_id": "63a0df8f53baa85ee0096638",
    "images": {"small": "thumbnails\/5245c582a3f9981a642c32561ed906d2.png"}
  },
  "pdf_sharing": null,
  "link_to_sign": null,
  "link_to_fill": null
}, {
  "_id": "63b520654edf85b79002f992",
  "pdf_file_id": "63b52064b8be365fdd072c16",
  "title": "33557-001.pdf",
  "updated_at": "2023-01-11 07:46:03",
  "tags": [{
    "title": "3",
    "color": "grey",
    "updated_at": "2023-01-20 08:47:54",
    "created_at": "2023-01-20 08:47:54",
    "_id": "63ca553ae8b09bcb6708dab2"
  }, {
    "title": "5",
    "color": "yellow",
    "updated_at": "2023-01-20 08:47:59",
    "created_at": "2023-01-20 08:47:59",
    "_id": "63ca553f3363b2065f0cbe31"
  }],
  "pdf_file": {
    "_id": "63b52064b8be365fdd072c16",
    "images": {"small": "thumbnails\/0c4323c3c623563bd2ad016b86e9f2fc.png"}
  },
  "pdf_sharing": null,
  "link_to_sign": null,
  "link_to_fill": null
}]


/* перебор ответа сервера */
function responseIteration() {
  resp.forEach(item => {
    const docID = item._id,
          docTitle = item.title;        
    /* перебор для вложенного массива объектов с тегами */     
    let tags = item.tags.reduce((acc,tag) => {
        const tagID = tag._id,
              tagColor = tag.color;      
        acc += `<li><span class="item ${tagColor}"></span></li>`;
        return acc;
    },'');

    //вставляем тэги в список
    let documentMarkup = `<div class="document-item" data-id="${docID}">
                            <a class="title">${docTitle}</a>
                            <ul class="tags-list">
                              ${tags}
                            </ul>
                          </div>` 
    
    resultsBlock.insertAdjacentHTML('afterbegin', documentMarkup);
  });
}


responseIteration();
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.item {
  display: inline-flex;
  width: 15px;
  height: 15px;
}

.grey {
  background: #d3d3d3;
}
.yellow {
  background: yellow;
}
.purple {
  background: purple;
}
.red {
  background: red;
}
<div id="results"></div>

▲ 1

Дело в том что в переменной documentMarkup вы уже в вёрстку заложили что должен быть всего один li. Значит нам надо отдельно собрать вместе все нужные нам li и только потом вставить в вёрстку

Для удобства и лучше читабельности создал 2 функции: li и documentItem. Далее просто проходимся по массиву с помощью forEach. А вот map используется чтобы вернуть видоизменённый массив, но вы просто перебираете массив, потому лучше использовать обычный for, for..of или forEach. Далее с помощью reduce проходимся по всем тегам и собираем их вместе

const resultsBlock = document.querySelector('#results');

const results = [{
  "_id": "63a0df907e9b89f949096c72",
  "pdf_file_id": "63a0df8f53baa85ee0096638",
  "title": "sample.pdf",
  "updated_at": "2022-12-19 22:02:57",
  "tags": [{
    "title": "1",
    "color": "purple",
    "updated_at": "2023-01-20 08:47:07",
    "created_at": "2023-01-20 08:47:07",
    "_id": "63ca550bdcc60c139b0eec5b"
  }, {
    "title": "8",
    "color": "red",
    "updated_at": "2023-01-20 08:48:09",
    "created_at": "2023-01-20 08:48:09",
    "_id": "63ca5549e8b09bcb6708dab3"
  }],
  "pdf_file": {
    "_id": "63a0df8f53baa85ee0096638",
    "images": {"small": "thumbnails\/5245c582a3f9981a642c32561ed906d2.png"}
  },
  "pdf_sharing": null,
  "link_to_sign": null,
  "link_to_fill": null
}, {
  "_id": "63b520654edf85b79002f992",
  "pdf_file_id": "63b52064b8be365fdd072c16",
  "title": "33557-001.pdf",
  "updated_at": "2023-01-11 07:46:03",
  "tags": [{
    "title": "3",
    "color": "grey",
    "updated_at": "2023-01-20 08:47:54",
    "created_at": "2023-01-20 08:47:54",
    "_id": "63ca553ae8b09bcb6708dab2"
  }, {
    "title": "5",
    "color": "yellow",
    "updated_at": "2023-01-20 08:47:59",
    "created_at": "2023-01-20 08:47:59",
    "_id": "63ca553f3363b2065f0cbe31"
  }],
  "pdf_file": {
    "_id": "63b52064b8be365fdd072c16",
    "images": {"small": "thumbnails\/0c4323c3c623563bd2ad016b86e9f2fc.png"}
  },
  "pdf_sharing": null,
  "link_to_sign": null,
  "link_to_fill": null
}];

function responseIteration() {
  const li = (color) => `<li><span class="item ${color}"></span></li>`;
  const documentItem = (id, title, tagsList) => `
    <div class="document-item" data-id="${id}">
      <a class="title">${title}</a>
      <ul class="tags-list">
        ${tagsList}
      </ul>
    </div>
  `;
  
  results.forEach(result => {
    const id = result._id;
    const title = result.title;
    const tagsList = result.tags.reduce((lis, tag) => lis + li(tag.color), '');
    
    resultsBlock.insertAdjacentHTML('afterbegin', documentItem(id, title, tagsList));
  });
}


responseIteration();
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.item {
  display: inline-flex;
  width: 15px;
  height: 15px;
}

.grey {
  background: #d3d3d3;
}
.yellow {
  background: yellow;
}
.purple {
  background: purple;
}
.red {
  background: red;
}
<div id="results"></div>