0

What i have achieved:

By using a effect-hook i'm using a fetch request to call a REST api and saving that data as JSON using a state-hook. I can render a specific element if i want to.

I've declared state:

const [apiR, setApiR] = useState([]); /

In my fetch request, i convert response to JSON and save to state.

.then((resp) => resp.json())
.then((resp) => setApiR([resp]))

i can display the data in app (this displays "TBTC 0.00780001")

<View>
    {apiR.map((item, index) => <Text key={index}> test {item.currencies[index].currency} {item.currencies[index].totalBalance} </Text>)}
</View>

using console.log(JSON.stringify(apiR, null, 2)) prints the following

[
  {
    "total": {
      "currency": "TBTC",
      "totalBalance": "0.00854046",
      "available": "0.00854046",
      "pending": "0"
    },
    "currencies": [
      {
        "active": true,
        "currency": "TBTC",
        "totalBalance": "0.00780001",
        "available": "0.00780001",
        "pending": "0",
        "btcRate": 1
      },
      {
        "active": false,
        "currency": "TETH",
        "totalBalance": "0",
        "available": "0",
        "pending": "0",
        "btcRate": 0.025145161625394714
      },
      {
        "active": true,
        "currency": "TXRP",
        "totalBalance": "37.8099",
        "available": "37.8099",
        "pending": "0",
        "btcRate": 0.00001958357570217716
      },
      {
        "active": false,
        "currency": "TBCH",
        "totalBalance": "0",
        "available": "0",
        "pending": "0",
        "btcRate": 0.024926423778461028
      },
      {
        "active": false,
        "currency": "TLTC",
        "totalBalance": "0",
        "available": "0",
        "pending": "0",
        "btcRate": 0.004572634826325412
      },
      {
        "active": false,
        "currency": "TZEC",
        "totalBalance": "0",
        "available": "0",
        "pending": "0",
        "btcRate": 0.005482556714309457
      },
      {
        "active": false,
        "currency": "TXMR",
        "totalBalance": "0",
        "available": "0",
        "pending": "0",
        "btcRate": 0.006804678411168356
      }
    ]
  }
]

At this point all works well. If i were to restart my app everything will still work fine. But what if i want to show all results in 'currencies' where 'active'= true?

If add the code:

var currencyArray = apiR[0].currencies; //getting the 'currencies' part
var filteredArray = currencyArray.filter(data => data.active); //getting all coins where 'active' = true
console.log(JSON.stringify(filteredArray, null, 2));

It works good, for now.

But if i restart app with this code i get the following error.

TypeError: undefined is not an object (evaluating 'apiR[0].currencies')

I suspect it's because apiR is just an empty array by default and the response data from the fetch request haven't been saved to state yet, because effect hooks run after the first render & after every update if i understood correctly.

If i remove the last 3 lines of code i added and instead print "apiR" after restarting the app, i can see that while it correctly renders the data from the response i saved to state("TBTC 0.00780001"), in console it just says that apiR is '[]'

I want to display filtered data when i start app, but don't know how to implement this

2
  • Bro, you want to see filtered data where 'active' = true when you start the app or you can't see data in view mode when you start the app with the existing code? Commented Jun 23, 2020 at 8:16
  • When i start the app with var currencyArray = apiR[0].currencies i get TypeError: undefined is not an object (evaluating 'apiR[0].currencies') Commented Jun 23, 2020 at 8:28

2 Answers 2

1

just use it like this:

var currencyArray = (apiR[0].currencies) ? apiR[0].currencies: [];
Sign up to request clarification or add additional context in comments.

3 Comments

I tried it, but i still get same error as before. TypeError: undefined is not an object (evaluating 'apiR[0].currencies') when i first try to start the app.
you could also check it like this: typeof(apiR[0].currencies) !== 'undefined' && apiR[0].currencies.length)
I still get the same error TypeError: undefined is not an object (evaluating 'apiR[0].currencies').
0

I am giving you a solution without using useState hook. Suppose you have a state like this:

this.state = {
  apiR: []
}

Your componentDidMount function should like this:

async componentDidMount() {
  await this.setState({
    apiR: [
      {
        "total": {
          "currency": "TBTC",
          "totalBalance": "0.00854046",
          "available": "0.00854046",
          "pending": "0"
        },
        "currencies": [
          {
            "active": true,
            "currency": "TBTC",
            "totalBalance": "0.00780001",
            "available": "0.00780001",
            "pending": "0",
            "btcRate": 1
          },
          {
            "active": false,
            "currency": "TETH",
            "totalBalance": "0",
            "available": "0",
            "pending": "0",
            "btcRate": 0.025145161625394714
          },
          {
            "active": true,
            "currency": "TXRP",
            "totalBalance": "37.8099",
            "available": "37.8099",
            "pending": "0",
            "btcRate": 0.00001958357570217716
          },
          {
            "active": false,
            "currency": "TBCH",
            "totalBalance": "0",
            "available": "0",
            "pending": "0",
            "btcRate": 0.024926423778461028
          },
          {
            "active": false,
            "currency": "TLTC",
            "totalBalance": "0",
            "available": "0",
            "pending": "0",
            "btcRate": 0.004572634826325412
          },
          {
            "active": false,
            "currency": "TZEC",
            "totalBalance": "0",
            "available": "0",
            "pending": "0",
            "btcRate": 0.005482556714309457
          },
          {
            "active": false,
            "currency": "TXMR",
            "totalBalance": "0",
            "available": "0",
            "pending": "0",
            "btcRate": 0.006804678411168356
          }
        ]
      }
    ]
  });

  var currencyArray = this.state.apiR[0].currencies; //getting the 'currencies' part
  var filteredArray = currencyArray.filter(data => data.active); //getting all coins where 'active' = true

  console.log(filteredArray);
}

After that you'll not get any error like undefined and your filteredArray will print as expected when you start your app.

8 Comments

When i start my app i can already render data from apiR. What i want to do is to filter the data saved in state and be able to render that when i first start my app.
Bro, I am sorry to not understand the problem properly. I am updating my answer.
I can take the data i get from a fetch request, turn it into JSON and save in state, then i can use data from state to render in view. My problem is if i want to filter that data. If i run my program once already and wait for effect hook to set response data to apiR, then if i write ´var currencyArray = apiR[0].currencies` it works. But it only works after i've already run my app once. If i restart my app completely, then i get error because apiR at this point is still only []
Try using the above procedure, you will get your expected result hopefully.
You can call the api in componentDidMount event with maintaining async and await.
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.