Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вопрос по json. (https://javascript.ru/forum/misc/85420-vopros-po-json.html)

alena0309 11.08.2023 19:09

Вопрос по json.
 
Здравствуйте. Имеется json. Вроде бы получилось вывести и стилизовать его на html, но не получается сделать фильтрацию. Т.е. поле, в котором при вводе данных name, будет фильтроваться. Что не так? Что Я упустила. Спасибо!

let users = [];
    let nameFilter = `name`;
    

    const render = () => {
        document.body.innerHTML = users
            .filter((item) => !nameFilter || item.name.toUpperCase().includes(nameFilter.toUpperCase())
                .map((item) => `<span class="name">${item.name}</span>`).join(``));
    }

    fetch(`users.json`)
        .then((res) => res.json())
        .then((data) => users = data)
        .then(render);

Aetae 11.08.2023 20:41

Смотри в консоль и читай что тебе пишет.

У тебя скобки криво расставлены: .map у тебя идёт после includes, а не после filter.

alena0309 11.08.2023 21:18

Цитата:

Сообщение от Aetae (Сообщение 552996)
Смотри в консоль и читай что тебе пишет.

У тебя скобки криво расставлены: .map у тебя идёт после includes, а не после filter.


Я прошу прощения, а как должно быть? В консоле написано, что map не функция.

Aetae 11.08.2023 21:56

Раскрыл запись и вынес наверх то что необязательно задавать налету:
const nameFilterUpper = nameFilter.toUpperCase();
const wrapItemNameInSpan = (item) => `<span class="name">${item.name}</span>`;

// сейчас у тебя так
const render = () => {
  document.body.innerHTML = users.filter((item) => {
    const itemNameUpper = item.name.toUpperCase();

    // естественно .map не функция, т.к. .includes возаращает Boolean, а у Boolean нет метода .map
    return !nameFilter || itemNameUpper.includes(nameFilterUpper).map(wrapItemNameInSpan).join(``)
  });
}

// а должно быть так
const render = () => {
  document.body.innerHTML = users.filter((item) => {
    const itemNameUpper = item.name.toUpperCase();
    
    return !nameFilter || itemNameUpper.includes(nameFilterUpper)
  }).map(wrapItemNameInSpan).join(``);
}

Так гораздо очевиднее проблема.

Если вы пока теряетесь в коротких записях рекомендую всё расписывать подробно, а не в одну строчку, так гораздо меньше шанс запутаться.

alena0309 11.08.2023 22:21

Цитата:

Сообщение от Aetae (Сообщение 552998)
Раскрыл запись и вынес наверх то что необязательно задавать налету:
const nameFilterUpper = nameFilter.toUpperCase();
const wrapItemNameInSpan = (item) => `<span class="name">${item.name}</span>`;

// сейчас у тебя так
const render = () => {
  document.body.innerHTML = users.filter((item) => {
    const itemNameUpper = item.name.toUpperCase();

    // естественно .map не функция, т.к. .includes возаращает Boolean, а у Boolean нет метода .map
    return !nameFilter || itemNameUpper.includes(nameFilterUpper).map(wrapItemNameInSpan).join(``)
  });
}

// а должно быть так
const render = () => {
  document.body.innerHTML = users.filter((item) => {
    const itemNameUpper = item.name.toUpperCase();
    
    return !nameFilter || itemNameUpper.includes(nameFilterUpper)
  }).map(wrapItemNameInSpan).join(``);
}

Так гораздо очевиднее проблема.

Если вы пока теряетесь в коротких записях рекомендую всё расписывать подробно, а не в одну строчку, так гораздо меньше шанс запутаться.

Поняла) Тогда завтра попробую вставить Ваш код.

alena0309 12.08.2023 09:19

Не знаю... Не получается вывести на html-страницу форму фильтра. Выводится только это:
fetch("users.json")
        .then(res=>res.json())

        .then(data=>{
            document.body.innerHTML = data.map((item)=>
                `
<div class="textcols-item show-modal">
<div class="trigger">
   <li style="list-style-type: none"><span class="name"><b><h3>${item.name}</h3></b></span></li>
  <br>
  <br>
   <i class="icono-iphone"></i> &nbsp ${item.phone}
  <br>
  <br>
   <i class="icono-mail"></i> &nbsp ${item.email}
   <br>
   </div>
   </div>
`).join(" ");
        })


А этот код не вывод:
const nameFilterUpper = nameFilter.toUpperCase();
    const wrapItemNameInSpan = (item) => `<span class="name">${item.name}</span>`;



    const render = () => {
        document.body.innerHTML = users.filter((item) => {
            const itemNameUpper = item.name.toUpperCase();

            return !nameFilter || itemNameUpper.includes(nameFilterUpper)
        }).map(wrapItemNameInSpan).join(``);
    }



    fetch(`users.json`)
        .then((res) => res.json())
        .then((data) => users = data)
        .then(render);

Aetae 12.08.2023 11:26

alena0309, всё работает:
<script>
let userJsonURL = 'users.json';
let users = [];
let nameFilter = `name`;

const nameFilterUpper = nameFilter.toUpperCase();
const wrapItemNameInSpan = (item) => `<span class="name">${item.name}</span>`;

const render = () => {
  document.body.innerHTML = users.filter((item) => {
    const itemNameUpper = item.name.toUpperCase();

    return !nameFilter || itemNameUpper.includes(nameFilterUpper)
  }).map(wrapItemNameInSpan).join(``);
}

// имитация users.json
userJsonURL = 'data:,' + JSON.stringify([
  {name: 'filtered'}, 
  {name: 'Vasya-name'}, 
  {name: 'Zlatan-name'}
]);

fetch(userJsonURL)
  .then((res) => res.json())
  .then((data) => users = data)
  .then(render);
</script>

alena0309 12.08.2023 12:00

Я, наверное, не так описала. У меня есть json. Код, который выводит на html-страницу:
fetch("users.json")
        .then(res=>res.json())

        .then(data=>{
            document.body.innerHTML = data.map((item)=>
                `
<div class="textcols-item show-modal">
<div class="trigger">
   <li style="list-style-type: none"><span class="name"><b><h3>${item.name}</h3></b></span></li>
  <br>
  <br>
   <i class="icono-iphone"></i> &nbsp ${item.phone}
  <br>
  <br>
   <i class="icono-mail"></i> &nbsp ${item.email}
   <br>
   </div>
   </div>
`).join(" ");
        })



Я никак не могу додуматься, как сделать форму поиск-фильтр по странице.


Часовой пояс GMT +3, время: 20:37.