Почему этот метод работает в консоли после загрузки данных, но не при использовании с событием в элементе? - PullRequest
0 голосов
/ 24 декабря 2018

Я пытался выяснить, почему addEventListener не работает с этой функцией.Players.getRushingYards () работает в консоли после загрузки данных.Я задал похожий вопрос несколько недель назад и получил указание на проблему со ссылкой на ключевое слово this.Я даже не использую это, поэтому не уверен, как это применимо.Я не делаю необходимый обратный звонок или что-то?Я пытаюсь скопировать данные в объект с именем 'Players', и после того, как данные возвращены, они работают в консоли, но снова, используя слушатель, он сообщает мне, что Players.data не определен.Если кто-то может помочь, это было бы очень признательно.Я пытался использовать простые функции и то, что я знаю о привязке, применении, вызове и т. Д. Безрезультатно.

window.addEventListener('load', getStats);
let players = {};
const xhr = new XMLHttpRequest
let output = "";
let txt;

// EXPORT AJAX REQUEST FOR STATS VIA MODULE
function getStats(e) {
  // const number = document.querySelector('input[type="number"]').value;();
  xhr.open('GET', `https://api.fantasydata.net/v3/nfl/stats/JSON/PlayerSeasonStats/2018`, true);
  xhr.setRequestHeader("Ocp-Apim-Subscription-Key", "api key goes here");

  xhr.onload = function () {
    if ( xhr.readyState === 4 && xhr.status === 200 ) {
      players.data = JSON.parse(xhr.response);
      console.log(players.data)
    }
    return players;
  }
  xhr.send();
  e.preventDefault();
  return players;
}

players.getRushingYards = () => {
  output = "";
  sorted = players.data.filter((el, ind) => {
    if ( el.RushingYards > 0 ) {
      return el
    }
  }).sort((a, b) => {
    if ( a.RushingYards  < b.RushingYards ) {
      return 1;
    }
    if ( a.RushingYards  > b.RushingYards ) {
      return -1;
    }
  });

  sorted.forEach((el, ind) => {
    output+= `<tr><td>${el.Name}</td><td>${el.RushingYards}</td><td>${el.RushingTouchdowns}</td><td>${el.ReceivingYards}</td><td>${el.ReceivingTouchdowns}</td><tr>`;
  })  

  let headers = `<th>Name</th><th>Rush Yards</th><th>Rush TD</th><th>Receiving Yards</th><th>Receiving TD</th>`;

  let combined = headers + output;

  document.querySelector(".stats").innerHTML = combined;
}

document.querySelector(".rushing-yards").addEventListener("click", players.getRushingYards);

Возвращенные данные - это объекты в массиве, которые выглядят примерно так (типичный разобранный объект JSON, который находится в массиве - для краткости я вынул большинство свойств)

response = [{
Name: "B.McManus"
ReceivingLong: 0
ReceivingTargets: 0
ReceivingTouchdowns: 0
ReceivingYards: 0
ReceivingYardsPerReception: 0
ReceivingYardsPerTarget: 0
ReceptionPercentage: 0
Receptions: 0
RushingAttempts: 0
RushingLong: 0
RushingTouchdowns: 0
RushingYards: 0
RushingYardsPerAttempt: 0},
{
Name: "E.Elliott"
ReceivingLong: 0
ReceivingTargets: 0
ReceivingTouchdowns: 0
ReceivingYards: 0
ReceivingYardsPerReception: 0
ReceivingYardsPerTarget: 0
ReceptionPercentage: 0
Receptions: 23
RushingAttempts: 192
RushingLong: 0
RushingTouchdowns: 11
RushingYards: 1250}]

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Players.data не определен в слушателе событий, пока getStats () не будет выполнена.Не могли бы вы попытаться объявить let Players = {data: []} во второй строке, чтобы проверить, сохраняется ли эта проблема.

0 голосов
/ 24 декабря 2018

Вы делаете асинхронный (AJAX) запрос в методе getStats, метод onload выполняется после получения ответа от сервера.Таким образом, данные, полученные с сервера, недоступны для вашего players.getRushingYards, так как они выполняются до получения ответа от сервера.Что вы можете сделать, это либо передать метод обратного вызова на getStats и вызвать его после получения данных от AJAX, например

function getStats(e, done) {
// done is the callback
// open XHR and set headers
xhr.onload = function () {
    if ( xhr.readyState === 4 && xhr.status === 200 ) {
        players.data = JSON.parse(xhr.response);
        console.log(players.data)
    }
    return done(players);
}
// xhr.send();

, либо вы можете скопировать код, следуя вашему методу getStats ивставьте его в onload.

xhr.onload = function () {
    if ( xhr.readyState === 4 && xhr.status === 200 ) {
        players.data = JSON.parse(xhr.response);
        console.log(players.data)
        // code to process players object 
    }
  }

. Вы можете проверить этот для дальнейшего уточнения / чтения.

...