1

I have been working on a javascript application and I am attempting to get the value of "id" using a different key/value pair. My JSON:

{
  "data": [
    {
      "value": "Hermitage Park",
      "type": "Park",
      "id": 2
    }
  ]
}

My Javascript:

function GetID(value) {
    var output = 0
    fetch("http://localhost:8088/data").then(storage => 
        storage.json()).then(items => {
            for (i = 0; i < items.length; i++) {              
                if (items[i]["value"] == value) {
                    output = i
                    break
                }
            }             
    })
    return output
}

When calling the function, I specified "Hermitage Park" as the value, hoping to get back the value of the "id" property, which is 2. It seems right to me, but it always returns 0 when it should be 2. I also tried items[value]["id"] and items[value].id, but nothing is working so far.

S. Ferrell
  • 171
  • 3
  • 11
  • 2
    It should return `null`, not `0`. Please see [How do I return the response from an asynchronous call?](https://stackoverflow.com/q/14220321/4642212). Next, if `items` is the object you’ve shown us, then `id` is at `items.data[0].id`. See [How can I access and process nested objects, arrays or JSON?](https://stackoverflow.com/q/11922383/4642212). – Sebastian Simon Oct 02 '19 at 21:46
  • You can use destructuring: `.then({data: items} => { ... })`. You can also break out of the loop once you've found the value. – Barmar Oct 02 '19 at 21:53
  • 1
    `fetch()` is asynchronous. You're returning `output` before it completes. – Barmar Oct 02 '19 at 21:54
  • See https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call – Barmar Oct 02 '19 at 21:54
  • Sorry, I had gotten mixed up (I am not very good at javascript) – S. Ferrell Oct 02 '19 at 21:57
  • Regardless of the asynch problems others pointed out, you're returning the index of the item, not the item id itself. – jas7457 Oct 02 '19 at 22:48

2 Answers2

0

Fetch is an Asynchronous function so you need to make GetID function async, Basically we can't return from async function and assign it into a variable. You can do following way:

async function GetID(value) {
  var output = null;
  let response = await fetch("../myjson.json");
  let result = await response.json();
  let data = result["data"];

  for (let i = 0; i < data.length; i++) {
    if (data[i]["value"] === value) {
      output = data[i]["id"];
    }
  }
  return output;
};
GetID("Hermitage Park").then( value => console.log(value));

From this function we will get back a Promise and then we can get that value from that Promise. As you can see the last line of the code https://dev.to/johnpaulada/synchronous-fetch-with-asyncawait

  • can't specify a .json file in the "fetch" function; it only works with "http" or "https" – S. Ferrell Oct 03 '19 at 14:50
  • 1
    @S.Ferrell, I was testing the code on my local machine so that's why I put local path. You can specify the http or https path whatever you want – James Dullat Oct 03 '19 at 17:18
0

fetch is an asynchronous method that returns a Promise. You're really close! What's missing is that GetID() is not returning the promise returned by fetch. Since it's not returning the promise there's no way for the caller of the function to wait for the value. The request eventually resolves, but the function has already returned 0 and your code has continued executing.

This can be rewritten as:

function GetID(value) {
    return fetch("http://localhost:8088/data")
        .then(resp => resp.json())
        .then(({ data }) => {
            const item = data.find(item => item.value === value);
            return item.id;
    });
}
Kai
  • 2,699
  • 1
  • 12
  • 7