Проблема с простым оператором if else при использовании Ajax - PullRequest
1 голос
/ 25 мая 2020

У меня небольшая и неприятная проблема (хотя я думаю, что она, вероятно, небольшая и глупая), и я занимаюсь этим часами, пробуя разные способы, меняя переменные и просто пытаясь посмотреть, сработает ли это.

У меня есть объект XMLHttpRequest и API, который возвращает заклинания и их эффекты. Однако в функции generateSpellBody оператор if() else() не выполняется должным образом. Продолжаю получать результат not a spell, как ни меняю условия, пробуя разные методы, пробовал indexOf(), json.parse et c. Я продолжаю получать результат условия else только внутри test.innerHTML

const spells = 'https://{my-spells-api-and-auth-key}';
const spellBtn = document.querySelector('.spell-btn');
const spellTextBox = document.querySelector('#spell-text');
let test = document.querySelector('.test');

function getJson (url, callback) {
    const xhr = new XMLHttpRequest;
    xhr.open('GET', url);
    xhr.onload = () => {
        if (xhr.status === 200) {
            let data = JSON.parse(xhr.responseText);
            return callback(data);
        }
    };
    xhr.send();
}

function generateSpellBody (data) {

     data.map(dat => {
         if (dat.spell === spellTextBox.value) {
            console.log(dat.spell);
            test.innerHTML = dat.spell;
        }
        else {
            test.innerHTML = 'not a spell';
        }

    });

}

spellBtn.addEventListener('click', (e) => {
    e.preventDefault();
    getJson(spells, generateSpellBody);
});

HTML:

    <form method='get'>
        <div class="form-group">
            <input type="text" class="form-control" id="spell-text" placeholder="Enter spell">
        </div>
        <button type="submit" class="spell-btn btn btn-default btn-light">Do spell</button>
    </form>

    <div class="test"></div>

Часть возвращенных данных JSON:

[
    {
        "_id": "5b74ebd5fb6fc0739646754c",
        "spell": "Aberto",
        "type": "Charm",
        "effect": "opens objects"
    },
    {
        "_id": "5b74ecfa3228320021ab622b",
        "spell": "Accio",
        "type": "Charm",
        "effect": "Summons an object",
        "__v": 0
    },
    {
        "_id": "5b74ed2f3228320021ab622c",
        "spell": "Age Line",
        "type": "Enchantment",
        "effect": "Hides things from younger people",
        "__v": 0
    },
    {
        "_id": "5b74ed453228320021ab622d",
        "spell": "Aguamenti",
        "type": "Charm",
        "effect": "shoots water from wand",
        "__v": 0
    }
]

Ответы [ 2 ]

2 голосов
/ 25 мая 2020

Прежде всего, функция map не является подходящей функцией для использования здесь, используйте for l oop.

Переходя к проблеме в вашем коде, когда условие if оценивается как Блок false, else запускается, и вы получаете результат not a spell. Ваш код найдет и обновит DOM правильно, если правильное заклинание находится в последнем индексе массива данных, в противном случае, если вы нашли правильное заклинание, в следующей итерации блока l oop, else запустится и перезапишите правильное заклинание с помощью not a spell.

Либо удалите блок else, либо сломайте l oop, когда найдете правильный spell.

Я бы рекомендовал удалить блок else и установить test.innerHTML после того, как l oop закончился, потому что вы не хотите обновлять DOM каждый раз, когда условие if оценивается как false. Этот подход показан во фрагменте кода ниже.

const spellBtn = document.querySelector('.spell-btn');
const spellTextBox = document.querySelector('#spell-text');
let test = document.querySelector('.test');

const data = [
  {"spell": "Aberto" },
  { "spell": "Accio" },
  { "spell": "Age Line" },
  { "spell": "Aguamenti" }
];

function generateSpellBody(data) {
  let text = 'not a spell';

  for (let i = 0; i < data.length; i++) {
    if (data[i].spell === spellTextBox.value) {
      text = data[i].spell;
      break;
    }
  }

  test.innerHTML = text;
}

spellBtn.addEventListener('click', (e) => {
  e.preventDefault();
  generateSpellBody(data);
});
<form method='get'>
  <div class="form-group">
    <input type="text" class="form-control" id="spell-text" placeholder="Enter spell">
  </div>
  <button type="submit" class="spell-btn btn btn-default btn-light">Do spell</button>
</form>

<div class="test"></div>
0 голосов
/ 25 мая 2020
 function generateSpellBody (data) {
    var newArray = data.map(dat=>dat.spell ===spellTextBox.value?dat.spell:'not a spell')

   for (let i =0; i < newArray.length; i++){
      test.innerHTML = newArray[i];
   }

 };

вы можете использовать функцию timeOut внутри для l oop, чтобы увидеть эффект

for (let i =0; i < newArray.length; i++){
     setTimeout(function(){ test.innerHTML = newArray[i]; }, 3000);

   }


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...