0

I was trying to run the function getJarak() each time my render run the map looping. I have tried many things but I'm still getting an error using async await.

 const getJarak = async (lat, lng) => {
      const lats = this.state.lastLat;
      const lngs = this.state.lastLong;

      try {
        const response = await axios.get('https://maps.googleapis.com/maps/api/distancematrix/json?origins=' + lats + ',' + lngs + '&destinations=' + lat + ',' + lng + '&key=APIKEY');
        console.log(response.data.rows[0].elements[0].distance.text);
        const data = response.data.rows[0].elements[0].distance.text
        return data

      } catch (error) {
        console.log("error", error);
      }
    }

   return this.state.healthCareQ.map((health, id) => {
        return (
          <TouchableOpacity key={id} activeOpacity={.6} onPress={() => {
            this.props.navigation.navigate('HealthcareDisSubdis', { health });
          }}>
            <View style={stylesLocation.health} >
              <View style={{ flex: 1, borderRadius: 14 }}>
                <Image
                  style={stylesLocation.healthImage}
                  source={health.logo === "" || health.logo === null ? require('../../asset/noimage.png') : { uri: `${health.logo}` }}
                />
              </View>

              <View style={stylesLocation.healthDetails}>
                <View style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
                  <Text style={{ fontSize: 14, fontWeight: 'bold', width: 230, flexWrap: 'wrap' }}>
                    {health.hfc_name}
                  </Text>
                  <Text style={{ fontSize: 12, color: '#A5A5A5', paddingTop: 5, width: 215, flexWrap: 'wrap' }}>
                    {health.address1}
                  </Text>
                </View>
              </View>
              <View style={{ flex: 0.90, justifyContent: 'center' }}>
                {/* <Text style={{ fontWeight: 'bold' }}>{parseFloat(health.distance / 1000).toFixed(1)} KM</Text> */}
                <Text style={{ fontWeight: 'bold' }}>{getJarak(health.latitude, health.longitude)}</Text>
              </View>
            </View>
          </TouchableOpacity>
        );
      })

Here my error

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • 4
    Welcome to Stack Overflow. Please don't upload [images of code](https://meta.stackoverflow.com/a/285557/3082296). They can't be copied to reproduce the issue, they aren't searchable for future readers and they are harder to read than text. Please post the actual code **as text** to create a [mcve]. – adiga Jan 03 '20 at 03:50
  • please check your values, you are displaying object as text in your code. – Jigar Shah Jan 03 '20 at 04:16
  • Does this answer your question? [Reactjs async rendering of components](https://stackoverflow.com/questions/27192621/reactjs-async-rendering-of-components) – Emile Bergeron Jan 03 '20 at 04:22
  • @JigarShah , my value (response.data.rows[0].elements[0].distance.text) was string – Syafiq Shuib Jan 03 '20 at 05:13
  • Please post a part of the error message as text so that it is searchable for future readers – adiga Jan 03 '20 at 12:35

2 Answers2

1

Usually, when there is a delay in getting data we need to show some sort of loading icon and once we get the data we remove the loader and display data so maybe you can have a componentDidMount where you will make the call and set the data in the state and in the render function you can check if data is present then display it or else you can display loader

jaswanth
  • 515
  • 2
  • 7
1

The getJarak function returns a promise that resolves to text. So you can't render it. Whatever you put inside that Text element has to be a string, not a promise of a string.

You should hold the text in your component's state, and render that in your Text element, i.e. <Text>{this.state.text}</Text>. Then when you run getJarak it needs to update the component's state with this.setState({text: newText}), rather than returning the value like it currently does.

Flagship1442
  • 1,688
  • 2
  • 6
  • 13
  • is that {this.state.text} will display the different value of distance. Because i have 25 set of lat lng. which line should i put the function getJarak to be run in render? – Syafiq Shuib Jan 03 '20 at 05:11
  • I don't think you want to be triggering an API call every time you re-render... Depending on what else is going on on this screen you could end up triggering this hundreds or thousands of times a minute. I don't know exactly what this API call is doing, but normally you would want to trigger it if **1)** The user presses a button, **2)** The user types something, **3)** if the component has just mounted (i.e. put it in the `componentDidMount() {...}` method of your component or **4)** At some regular predefined interval. – Flagship1442 Jan 03 '20 at 05:34
  • 1
    This should be answer. Yes, use `componentDidMount` lifecycle function. `render` lifecycle function should be a pure function (no side-effects). – Drew Reese Jan 03 '20 at 06:18
  • @DrewReese , i already fetch the data from backend (api) inside componentDidMount, and then i want using the distance matrix api to get the distance. – Syafiq Shuib Jan 03 '20 at 07:13
  • 1
    @SyafiqShuib Once you have the response from your API call you can manipulate the data you receive in whatever way you need. But eventually you will finish by setting your state as the text you want to display on the screen. Just to check are you trying to display just one text element, or are you trying to display a list of results? – Flagship1442 Jan 03 '20 at 07:18
  • @James, actually, my render already display the list of result that i want. But i want to run the function getJarak(). The parameter for getJarak() was get from data in map looping. – Syafiq Shuib Jan 03 '20 at 07:37
  • @SyafiqShuib I'm struggling to understand what you mean. You say you have the list of results you want and they're displaying correctly. What do you expect to have changed after you run the `getJarak` function? – Flagship1442 Jan 03 '20 at 08:24
  • @James my list of result have latitude and longtitude, getJarak function will be use to return the distance from origin to destination. You can see my getJarak function above. – Syafiq Shuib Jan 06 '20 at 04:46