0

I have tried several other options on how to do this, such as

How to read a nested JSON in React?

Can't access nested JSON Objects in React

I am trying to query the API when I click "Search". Currently, when I click "Search", the API queries the correct URL, but I am having trouble accessing the returned data. The data that is sent back looks like this:

{
  "option_activity": [
    {
      "id": "5f033b253c8cf100018a312f",
      "bid": "0.6",
      "ask": "1.0",
      "midpoint": "0.8",
      "updated": 1594047269
    },
    {
      "id": "5f033b253c8cf100018a312f",
      "bid": "0.6",
      "ask": "1.0",
      "midpoint": "0.8",
      "updated": 1594047269
    },

With hundreds of these items. What it looks like in the console:

enter image description here

What I am doing to query the api:

  fetchData() {
        var val = this.state.searchedValue;
        var url = "URL/TO/API"
        fetch(url)
    .then(res => res.json())
    .then((res) => {
            const itemsList = res.option_activity;

            this.setState({
                items: itemsList
            },
            function () {
                console.log(itemsList);
            }
            );
            // console.log(this.state.items)
            
        },
        
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
        
             console.log(error);

        },
        // console.log(this.state.items)
    )
}

While the network logs the response from the API, the console log just logs an empty array "[]" for this.state.items, which is initialized to an empty array. How can I save the contents of "option_activity" into an array "items", where I can access the id, bid, ask, midpoint etc through this array of items?

So, items[0] would have items[0].id, items[0].midpoint, etc accessible.

Thanks in advance

Solution is in the comments of the correctly marked answer

9
  • This looks like it should work and give you an array of id for each element, so it seems like it's not enough code to reproduce the problem. If you want the full structure, remove the map call. Are you getting any errors? The only console.log is in the error handler so it'd make sense that that would be empty if it does fire. Commented Jul 10, 2020 at 3:07
  • @Santoshi24 , the setState method is async operation , console.log will print an empty array only , since that was the initial state., You can use the callback to see if state is getting updated or not Commented Jul 10, 2020 at 3:08
  • @Satoshi24 Your console.log is happening in the error function, are you sure there isn't an error occuring before setting those items to the state? Commented Jul 10, 2020 at 3:13
  • @HarmandeepSinghKalsi Using a callback yields the same empty array. Commented Jul 10, 2020 at 4:07
  • @RyanWilson made a mistake of logging in error. Removing it and logging thru a callback still yields an empty array Commented Jul 10, 2020 at 4:07

2 Answers 2

0

Are you hitting an API URL on a different domain? If so, you may well be actually getting a CORS error. If you try to programmatically hit an endpoint on another domain, the browser will check for specific headers to ensure the API allows you to do that. If it doesn't see those headers, it will throw an error (which you should see in your console). The network tab will still show the expected payload, but it won't be made accessible to you in Javascript.

Right now, you are only logging to the console on an error. So, if you are seeing the response in the network tab, but are always ending up in the error handler, that indicates something is wrong with the response (CORS, or somehow maybe you are returning malformed data that can't be parsed as JSON).

You should also note that your current log isn't particularly useful. You are only ever printing out the old value of items. Since you clearly never set it (note that you are in the error handler), you would expect this value to be whatever it was before trying to set the value of items (presumably the initial empty array).

Sign up to request clarification or add additional context in comments.

6 Comments

Learning about CORS errors is interesting - I see no related CORS error in the console. I removed the logging to console out of the error (put it there by mistake) and still am unable to log the array of items apart from an empty array
Can you update your question to include the console in the correct location? If it is getting to the then clause, then re-read my 3rd paragraph. If you are still just doing a console.log(items), it won't work as you expect. You may want to actually do a console.log(this.state.items) within the render function, or to console.log(itemsList) within your then clause.
LOL. I think the error is simpler than I realized. this is what im getting now: SyntaxError: Unexpected token < in JSON at position 0. Updating code...
Hah, yea, that often happens when you have some sort of error in your api server, and it is actually returning HTML instead of JSON.
Ahh. that makes sense, in the docs they use a curl query with -H "accept: application/json" at the end. Any idea how to incorporate that into my query?
|
0

First, you don't need to use map to convert the returned activity list if you want to access to id, bid, etc.

                const itemsList = res.option_activity;

                this.setState({
                    items: itemsList
                });

Second, if you want to read state right after using setState, you need to use a callback, similar to the following code snippet.

this.setState({ boardAddModalShow: true }, function () {
    console.log(this.state.boardAddModalShow);
  });

This is because according to React docs

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

2 Comments

Removing mapping didn't work, and I added a callback to print the items but it logged an empty array again.
Nevermind. It does work, I didn't realize that I was receiving HTML instead of JSON.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.