Geschrieben von

JavaScript: fetch()

WebDev

Mit ES6 wurden in JavaScript Promises eingeführt, um asynchrone Operationen einfacher abzuwickeln. Bei einem Promise handelt es sich um ein Objekt, der folgende Zustände haben kann: pending, fulfilled und rejected. Das gute dabei ist, dass sobald ein Promise in den Zustand fulfilled oder rejected kommt, Methoden wie then() oder catch() angehangen werden können, um auf die Zustände zu reagieren.

Eine weitere wichtige Methode, die Requests verarbeitet, ist fetch(). fetch() ermöglicht HTTP-Requests, ähnlich wie XMLHttpRequests (XHR). Der Unterschied zu XHR ist, dass fetch() Promises benutzt, wodurch ein schönerer Code entsteht und die “Callback Hell” vermieden werden kann.

fetch() erklärt

Die fetch()-Methode kann 2 Argumente entgegen nehmen:

  • Die URL bzw. den Pfad zur Ressource, die abgerufen wird.
  • Als zweites Argument kann optional ein Objekt mit Optionen mitgegeben werden.

Zunächst wird also der Endpoint angegeben (hier mit einer Beispiel-API von https://jsonplaceholder.typicode.com/):

fetch('https://jsonplaceholder.typicode.com/users');

Die Optionen können nun noch optional als Objekt mitübergeben werden:

fetch('https://jsonplaceholder.typicode.com/users', {
// Hier kommen die Optionen
});

Der Einfachheit halber schauen wir uns zunächst ein Beispiel ohne Optionen an. Dazu loggen wir die fetch()-Methode in die Konsole:

Wie man sehen kann, wird ein Promise zurückgegeben. fetch() basiert also auf einem Promise. Dementsprechend können wir mit fetch() auch Promise-Methoden wie then() und catch() benutzen oder auch async/await. Deshalb hängen wir jetzt ein then() an. Da uns fetch() einen Response zurückgibt, werden wir diesen abfangen und im Parameter “response” mitgeben. Gleichzeitig loggen wir diesen Response in die Konsole, um zu sehen, was uns fetch() zurückgibt:

Wir sehen, dass die Antwort erfolgreich war (ok: true), den korrekten Status Code zurückliefert (status: 200) und dass ein Body (body: ReadableStream) mit den benötigten Daten zurückgegeben wird. Leider kann auf die Daten nicht direkt über das response-Objekt zugegriffen werden. Um auf die Daten zuzugreifen müssen wir eine Methode anwenden, die die Daten in JSON umwandelt und zurückgibt. Zunächst hängen wir also die entsprechende Methode an:

Das gibt ein weiteres Promise-Objekt zurück, welches wir wieder abfangen müssen. Wir speichern dies im Parameter “data” innerhalb einer weiteren then()-Methode. “data” geben wir nun in der Konsole aus, da hier unsere eigentlichen Daten vorliegen (hier handelt es sich um Test-Daten):

Wenn ich auf einzelne Datenzeilen zugreifen möchte, könnte ich das entsprechend im Endpoint mitgeben:

fetch('https://jsonplaceholder.typicode.com/users/2');
fetch('https://jsonplaceholder.typicode.com/users/8');

Mit dieser fetch()-Methode greife ich z.B. auf die Zeilen 2 und 8 der Nutzer-Datenbank zu. Was wenn wir auf einen Datensatz zugreifen, der nicht existiert?:

Wie man sehen kann, bekommen wir einen Fehlercode (404) und ein leeres Objekt zurück. Obwohl also ein 404 zurückgegeben wird, wurden die then()-Methoden dennoch ausgeführt. Um den Fehler abzugreifen und eine entsprechende Meldung zurückzugeben, könnte man meinen, dass wir auf catch() zurückgreifen können:

Wie man sehen kann, wird die Fehlermeldung trotz eines 404 nicht zurückgegeben. Und das ist die Art und Weise wie fetch() arbeitet. Ganz gleich welcher Status Code zurückgegeben wird, fetch() wird dennoch erfolgreich ausgeführt (außer bei Netzwerk-Problemen o.Ä.). Die Lösung ist, dass man mit einem if arbeitet:

Da der Datensatz hier nicht vorhanden ist, wird die entsprechende Fehlermeldung ausgegeben. Wenn der Datensatz vorhanden ist, läuft alles durch:

Was wenn wir aber Daten nicht nur abfragen möchten, sondern Daten einfach nur dem Server übermitteln wollen? Hier kann man die entsprechenden Optionen wie POST als zweiten Parameter in der fetch()-Funktion mitgeben:

fetch('https://jsonplaceholder.typicode.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
},
  body: JSON.stringify({
    name: 'New Name',
})
}).then(response => {return response.json()})
.then(data => console.log(data));

Zur Erklärung:

  • Mit “method” kann eine beliebige HTTP-Methode gesetzt werden.
  • Mit “headers” muss der Content-Type mitgegeben werden, den fetch() benötigt.
  • Im “body” werden die Daten, die übermittelt werden sollen, als JSON angegeben.

Besonders “headers” und “body” sind wichtig, wenn man JSON an den Server schickt. Erst wenn man den richtigen Header setzt und im Body die zu übermittelnden Daten als JSON formatiert, können die Daten korrekt ankommen: