• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Frage fetch API liefert nur undefined

Chronos

Aktives Mitglied
Hallo Forum,

ich bin leider etwas verwirrt was die Handhabung der fetch-API angeht.

Ich kann ganz normal eine Abfrage absetzen und innerhalb meiner Funktion auch darauf zugreifen.
in der Zeile 18 mit simplifiedResults returne ich diese.

Oben beim button kommt allerdings nur undefined zurück, wieso?
Meine Vermutung ist das die Abfrage beim klicken des Buttons noch nicht durch ist - kann das sein?

Code:
window.onload = () => {
    document.getElementById('getObj').addEventListener('click', () => {
        let bla = getLabelfromObject('Q24034552');
        console.log(bla);
    });
};

function getLabelfromObject(objectValue) {
    const url = 'google.de'

    fetch(url)
        .then(response => {
            // Parse as JSON
            return response.json();
        })
        .then(parsedData => {
            simplifiedResults = wdk.simplifySparqlResults(parsedData);
            return label = simplifiedResults[0].item.label;
        })
        .catch(error => {
            console.log(`Fetch didn't work: ${error.message}`);
        });
}
 
Werbung:
Meine Vermutung ist das die Abfrage beim klicken des Buttons noch nicht durch ist - kann das sein?

Möglich. Ich kenne die Fetch-API nicht, aber was ich hier auf Anhieb hässlich finde, sind die beiden gechainten .then(). Auch wenn das so in der Doc steht.

Warum machst du das überhaupt auf diese Weise? Du könntest alternativ dazu die Promise-API einsetzen.
 
Zuletzt bearbeitet:
Finde ich bequemer als jQuery oder die bisherige Art und Weise zu benutzen. Den Teil mit der promise-API verstehe ich nicht. Fetch selber liefert promises zurück, dafür ist das then ja da (kann man vllt auch anders formatieren).

Jedenfalls ist fetch nur ein Ajax Request und das an sich geht ja.
Weiß nur nicht wieso ich da nicht auf die variable bzw den Rückgabewert zugreifen kann
 
Werbung:
Ich bin gerade im Office und habe wenig Zeit. Deshalb nur ein paar Stichpunkte zum Thema:
- Drop die Fetch-API und verwende ein Framework, das einen $http Provider mitbringt (Angular, React, Vue, etc.)
- Du kannst entweder Promises oder Observables für AJAX-Requests verwenden. Observables sind Teil von RxJS und werden standardmäßig in Angular 2 eingesetzt.
- Es sollte immer nur jeweils ein Handler für Resolve/Reject bzw. then(), .catch() vorhanden sein.
- Zur Vermeidung von chained Callbacks (Pyramid of Doom) bietet sich die 'q' Library an.
- Interessant wäre auch async/await
https://ponyfoo.com/articles/understanding-javascript-async-await.
- Wenn du über den jQuery-Level hinaus bist, schau dir mal TypeScript an. Ist quasi das, was SASS für CSS ist (Superset) und erleichtert die Arbeit mit JavaScript.
 
Also ein Framework zu verwenden wäre mit Kanonen auf Spatzen zu schießen. Ich mache ja nicht viel mit dem Request, ich bekomm ein JSON zurück und rendere ein wenig daraus und das war es auch schon. Ich benutze für so etwas ganz sicher kein Framework. Eigentlich will ich es so nativ wie möglich, muss aber nicht im IE7 laufen...

Asyn Await könnte schon eher passen 'q' vllt auch - aber eigentlich suche ich eine native Lösung.
 
Werbung:
So ich habe es jetzt selber mal probiert:
Code:
fetch('https://www.google.de').then(
    function(response) {
      console.log('do something with ', response);
    })
    .catch(function(error) {
    console.log('error ', error);
  });

liefert wie erwartet einen 200 zurück. Wenn du das Response Objekt innerhalb des Handlers bearbeitest, gibt es keine Probleme. Wozu dein zweites .then()?
 
.json ist lediglich ein Format und aus deiner Eingangsfrage geht nicht hervor, was du bezweckst.

Ein gängiger Usecase wäre:
- man sendet einen GET Request an einen Endpoint (URL)
- Das Response Object wird zu json transformiert und bedarfsweise weiterverarbeitet. Im Ergebnis erhält man dann bsw. eine Collection (Array) von Objekten, die in einer Variablen gespeichert wird. Sagen wir mal, es handele sich um die Antworten dieses Threads.
- Um über die Antworten innerhalb des HTML mittels JavaScript zu iterieren, kämen dann entsprechende Frameworks in Spiel, welche eine Template-Syntax mitbringen.
 
Werbung:
wtf? Nein, kein Framework. Es ist auch irrelevant was ich genau bezwecke. Die Frage war wie ich mit der fetch API einen Wert zurückgeben kann auf den ich in dem Button oder einer anderen Funktion Zugriff habe und Punkt.

Was ich konkret mache ist eine Anfrage an eine API absetzen, das gibt mir ein JSON zurück, das bearbeite ich ein wenig und gebe es als HTML aus und nichts weiter, ist aber für mein Problem komplett irrelevant.
Das ist sogar so simpel das es einfach nur etwa 7, vllt auch mal 10 Divs werden.

Also nochmal: wieso ist das an der Stelle undefined? Race-condition, Variable nicht zugreifbar etc etc. ?

Noch deutlicher, letztlich bekomm ich dann in dem Block einen Wert zurück meinetwegen Fub345, den will ich oben an der stelle mit dem Button benutzen. Nix weiter, ich nutz doch kein Framework was weiß ich wieviele KB groß ist dafür, wozu denn? Die Anfrage geht, ich bekomm was zurück, ich verarbeite das nur falsch

(PS: du tendierst sehr, sehr gern dazu zu sagen: "nimm doch Angular" - das ist nicht viel besser als die Leute die einem wegen jedem Quark jQuery vorschlagen, hätte ich Angular gewollt, hätte ich danach gefragt)

B2T: also entweder liegt es daran, dass die Anfrage noch nicht durch ist, dann kann ich aber in den Promises bleiben oder ich nutze Await damit es sich wie eine synchrone verhält. Was Angular da wie wo macht ist mir egal
 
Also nochmal: wieso ist das an der Stelle undefined? Race-condition, Variable nicht zugreifbar etc etc. ?

Async Problem. versuche es mal so:
Code:
(function () {
    document.querySelector('button').addEventListener('click', function () {
      fetchData('https://www.google.de')
        .then( data => console.log(data));
    });
    async function fetchData(url) {
      try {
        const response = await fetch(url);
        return await response;
      }
      catch (err) {
        console.log('fetch failed', err);
      }
    }
  })();
 
Werbung:
Zurück
Oben