Fetch API with API key

I am making a lot of breaks in the process of trying to learn to code and I am generally not satisfied with how it is going for me. But this time I finally managed to get some data from APIs out there and thought it will be better this time. However, as soon as the API is more complex I am stuck.

Could anyone tell me what should I do with this code to get the data? I always get ‘TypeError: Failed to fetch’ in the console.

This is my code:

const url = "http://api.football-data.org/v2/matches";
fetch(url, {
  method: "GET",
  withCredentials: true,
  headers: {
    "X-Auth-Token": "ef72570ff371408f9668e414353b7b2e",
    "Content-Type": "application/json"
  }
})
  .then(resp => resp.json())
  .then(function(data) {
    console.log(data);
  })
  .catch(function(error) {
    console.log(error);
  });

@Ivan999 Use https for the url and drop the “Content-Type” property headers.object.

const url = "https://api.football-data.org/v2/matches";
fetch(url, {
  method: "GET",
  headers: {
    "X-Auth-Token": "ef72570ff371408f9668e414353b7b2e"
  }
})
3 Likes

Thank you very much!

I hope it is not too much to ask for further help?

window.addEventListener("load", function() {
  const url = "https://api.football-data.org/v2/competitions/2014/standings";
  fetch(url, {
    method: "GET",
    headers: {
      "X-Auth-Token": "ef72570ff371408f9668e414353b7b2e"
    }
  })
    .then(resp => resp.json())
    .then(function(data) {
      console.log(data);

      let output = "";
      output += `<p>Started on ${data.season.startDate}, ending on ${data.season.endDate}</p>`;

      let overallTable = "";

      for (let i = 0; i < data.standings[0].table.length; i++) {
        overallTable += `${data.standings[0].table[i].team.name} 
        ${data.standings[0].table[i].points}`;
      }

      document.getElementById("output").innerHTML = output;
      document.getElementById("overallTable").innerHTML = overallTable;
    })
    .catch(function(error) {
      console.log(error);
    });
});

This is my new code and this is what I get : http://prntscr.com/pbiwec

So, I get correct data and data I wanted, but ideally I would like to loop with forEach (I have tried that as well, but couldn’t get it to work) and get this data as the real table. I know I should use document.createElement to create table rows and table data, so I could get for example
Real Madrid 14
Real Sociedad 13
Atletico 13 etc
but I can’t get it right, could you help me please?

I have confidence that you can do this yourself. Give it a try and update your code with what you try, so if you get stuck, we can guide you instead of just showing you the code.

EDIT: I have created a modified version of the array you have in your JSON data. This is how I would approach such a problem. There is nothing wrong with going the createElement route, but I personally use the method below because I think the code is more readable. I suggest not looking at the code below unless you are totally stuck.

const tableData = [
  { team: 'Real Madrid CF', points: 14 },
  { team: 'Real Sociedad', points: 13 },
  { team: 'Atletico ', points: 13 }
];

const rowDataHTML = tableData.reduce(
  (html, { team, points }
) => html += `
  <tr>
    <td>${team}</td>
    <td>${points}</td>
  </tr>
`, '');

document.getElementById("table").innerHTML += rowDataHTML;
1 Like

Thanks and I am not looking at the code yet :slight_smile:

window.addEventListener("load", function() {
  const url = "https://api.football-data.org/v2/competitions/2014/standings";
  fetch(url, {
    method: "GET",
    headers: {
      "X-Auth-Token": "ef72570ff371408f9668e414353b7b2e"
    }
  })
    .then(resp => resp.json())
    .then(function(data) {
      console.log(data);

      let output = "";
      output += `<p>Started on ${data.season.startDate}, ending on ${data.season.endDate}</p>`;

      let table = document.createElement("table");
      let thead = document.createElement("thead");
      let trow = document.createElement("tr");

      for (let i = 0; i < data.standings[0].table.length; i++) {
        // overallTable += `${data.standings[0].table[i].team.name}
        // ${data.standings[0].table[i].points}`;

        let td = document.createElement("td");
        td.appendChild(document.createTextNode("testing"));
        // document.createTextNode(data.standings[0].table[i].team.name)

        trow.appendChild(td);
      }

      thead.appendChild(trow);
      table.appendChild(thead);

      document.getElementById("output").innerHTML = output;
      document.getElementById("overallTable").innerHTML = table;
    })
    .catch(function(error) {
      console.log(error);
    });
});

I am trying with something like this but now instead of getting data from the API I get this: http://prntscr.com/pbjo1d

I would have to sleep now and will try to fix this tomorrow, thanks for your help :slight_smile:

You are trying to assign an element (table) to the innerHTML property of the element with id="overallTable. Instead, you should be assigning a string value to theinnerHTML` property. The other option is to append the table to the element with id=“overallTable”.

1 Like

@Ivan999 To help you achieve what I think you were trying to do with the “testing” text, here is a modified version of your code:

      let table = document.createElement("table");
      let thead = document.createElement("thead");
      let trow = document.createElement("tr");
      
      thead.appendChild(trow);
      table.appendChild(thead);
    
      for (let i = 0; i < data.standings[0].table.length; i++) {
        let trow = document.createElement("tr");
        overallTable += `${data.standings[0].table[i].team.name}
        ${data.standings[0].table[i].points}`;

        let td = document.createElement("td");
        td.appendChild(document.createTextNode("testing"));
        trow.appendChild(td);
        td = document.createElement("td");
        td.appendChild(document.createTextNode("testing"));
        trow.appendChild(td);
        table.appendChild(trow);
      }
1 Like

Thanks a lot, I understand what is going on now :slight_smile:


      let table = document.createElement("table");
      let thead = document.createElement("thead");
      let trow = document.createElement("tr");

      thead.appendChild(trow);
      table.appendChild(thead);

      for (let i = 0; i < data.standings[0].table.length; i++) {
        let trow = document.createElement("tr");
        // overallTable += `${data.standings[0].table[i].team.name}
        // ${data.standings[0].table[i].points}`;

        let td = document.createElement("td");
        td.appendChild(
          document.createTextNode(`${data.standings[0].table[i].team.name}`)
        );
        trow.appendChild(td);
        td = document.createElement("td");
        td.appendChild(
          document.createTextNode(`${data.standings[0].table[i].points}`)
        );
        trow.appendChild(td);
        table.appendChild(trow);
      }
      document.getElementById("output").innerHTML = output;
      document.getElementById("overallTable").appendChild(table);
    })

I commented out this overallTable +=… because it looks unnecessary, it works without that too… now this is what I have: http://prntscr.com/pbv1a0

Just for curiosity, is this possible with forEach as well?

Looked at your code too now and it looks very nice, I will type it out now to see how could I use it with API data instead of hardcoding it :slight_smile:

You can, but since you can use reduce, why would you?

Hi Randell,

I modified your code and googled about reduce method but I don’t understand everything yet.

This is my modified code:

window.addEventListener("load", function() {
  const url = "https://api.football-data.org/v2/competitions/2014/standings";
  fetch(url, {
    method: "GET",
    headers: {
      "X-Auth-Token": "ef72570ff371408f9668e414353b7b2e"
    }
  })
    .then(resp => resp.json())
    .then(function(data) {
      console.log(data);

      const tableData = [
        {
          team: `${data.standings[0].table[8].team.name}`,
          points: `${data.standings[0].table[8].points}`
        }
      ];

      const rowDataHTML = tableData.reduce(
        (html, { team, points }) =>
          (html += `
      <tr>
        <td>${team}</td>
        <td>${points}</td>
        <br>
      </tr>
      `),
        ""
      );

      document.getElementById("table").innerHTML += rowDataHTML;
    });
});

If I place any number in square brackets, like for example data.standings[0].table[8].team.name I get correct team name, but when I place ‘i’ in [i] I obviously get the error ‘Uncaught (in promise) ReferenceError: i is not defined’
Where should I define the iterator here or there is no need for [i] at all?

You were only capturing the first element of the table array, but you need the entire array.

Within the last then callback, I recommend first destructuring the table (the array with 20 elements) out of the data object. Then, your reduce callback would use parameter destructuring to get the name and the points to use for the rest of the code you have written.

Don’t look below unless you want the solution to be spoiled for you.

window.addEventListener("load", function() {
  const url = "https://api.football-data.org/v2/competitions/2014/standings";
  fetch(url, {
    method: "GET",
    headers: {
      "X-Auth-Token": "ef72570ff371408f9668e414353b7b2e"
    }
  })
    .then(resp => resp.json())
    .then(function(data) {
      const { standings: [ { table: tableData } ] } = data;
      const rowDataHTML = tableData.reduce(
        (html, { team: { name } , points }) => html += `
          <tr>
            <td>${name}</td>
            <td>${points}</td>
         </tr>
        `, '');
      document.getElementById("table").innerHTML += rowDataHTML;
    });
});

Thank you very much, I will try to figure this out before looking at the code :slight_smile:

@Ivan999 NOTE: If your element with id="table" is a table element, then there is no reason to add the <br> after each </tr>.

Why we don’t get the first object with this code? I don’t understand it…

When I run the code above, I see all the data.

1 Like

Wow, strange :slight_smile: This is a real mystery for me, I really lose confidence that I will ever master JS…

A post was split to a new topic: Need help using AJAX to retrieve data from an API