0

This might have been discussed here a thousand times but I'm still unable to get this to work properly. Feel free to mark it as duplicate, I'm asking it nonetheless. Here's what I want:

  1. Fetch a JSON file from the web server
  2. Extract and return the JSON file content as JavaScript object
  3. Handle all errors that might occur in the above steps

All those steps should be done with the latest EcmaScript version that is feasible to be used in 2021 in a single function. Here's what I have:

async function getFile() {
  try {
    const response = await fetch("js/importantFile.json");
    if(response.ok) {
      return await response.json();
    } else {
      throw new Error(response.statusText);
    }
  } catch(error) {
    console.log("Failed to fetch JSON file: ", error);
  }
  return "";
}

Executing the code ends up with a promise object in state pending if I call the function as follows:

let jsonContent = getFile();

Besides this, am I missing something that needs to be done in terms of error handling?

ackh
  • 1,648
  • 2
  • 18
  • 36
  • How are you using the `getFile` function? Getting `pending` usually means you are not using `await` or `then` – evolutionxbox Mar 01 '21 at 15:47
  • `getFile`, like all `async` functions, returns a promise. You have to use that promise (e.g., via `await` or `.then` or similar, as @evolutionxbox said). Also, it's not best practice to convert errors to `""`. Just let the error propagate, so the caller knows something went wrong and what it was. So `getFile().then(data => /*...use data...*/).catch(error => /*...handle/report error...*/);` or the `await` equivalent if this is in an `async` function. – T.J. Crowder Mar 01 '21 at 15:49
  • @evolutionxbox Good point, I have edited the question accordingly. – ackh Mar 01 '21 at 15:51
  • Consider using `let jsonContent = await getFile();`, but make sure that it is being called in an async function. – evolutionxbox Mar 01 '21 at 15:51
  • 2
    FWIW, here's how to use it (and how to propagate errors): https://pastebin.com/ntB2zBEH – T.J. Crowder Mar 01 '21 at 15:53
  • I see, I attempted to write `let jsonContent = await getFile();` but that resulted in `Uncaught SyntaxError: await is only valid in async function`. My JavaScript knowledge isn't good enough yet but I know from other languages that `async`/`await` tends to "bubble up". Is there a way to rewrite that function so that it handles the dirty details without being forced to mark all other functions that call it with `async` too? – ackh Mar 01 '21 at 15:57
  • Sadly not. Anything that deals async must also be async. – evolutionxbox Mar 01 '21 at 15:57
  • Alright, same crap as in other languages then. Thanks for your quick reply. – ackh Mar 01 '21 at 15:59
  • @T.J.Crowder Thanks for the sample code. I'll go with that. – ackh Mar 01 '21 at 15:59
  • `getFile()` is an `async` function, so it _always_ return a Promise. Even if you `return "hello"`, the type returned is `Promise`, not `string`, which Typescript teaches very well. In consequence, since it's a Promise, it must be awaited with `await getFile()`. And indeed, `await` must be used inside an `async` function. – Jeremy Thille Mar 01 '21 at 16:01
  • 2
    _"same crap as in other languages"_ - curious, what makes it crap? (Edit: I've only ever used async in JS, so I don't have a clue about how else it could be done) – evolutionxbox Mar 01 '21 at 16:02
  • 1
    I don't see what's crap either. `async/await` is marvelous, on the contrary. – Jeremy Thille Mar 01 '21 at 16:03
  • I meant no disrespect towards `async`/`await`. They are great and do simplify code. I meant the fact that `async` "bubbles up" which I have plenty of experience with in C#. If you introduce it somewhere you end up marking all methods that use it with `async` as well which causes issues in deeply layered systems. – ackh Mar 01 '21 at 16:13
  • @ackh how dare you disrespect such a divine language! haha, I can see that being an issue though. – evolutionxbox Mar 01 '21 at 16:32

0 Answers0