Ankit Kumar
Ankit Kumar

Reputation: 1281

React Native: Open link on image click

I have an array arr of dictionary whose elements go like:

{url: 'https://stackoverflow.com/', picUrl: 'link to pic', ...}

I want to open the i-th link when the i-th image is clicked. My code goes as:

arr = this.example[key];
var arrayLength = arr.length;
for(var i = 0; i < arrayLength; i++) {
  console.log(arr[i]);
  console.log(arr[i].url);
  var x = arr[i].url;
  views.push(
    <View>
      <ImageBackground
        source={{uri: arr[i].picUrl}}
        style={{ width: '100%',aspectRatio: 1, height: undefined }}>
        <TouchableOpacity
          onPress={() => Linking.openURL(x)}
// or     onPress={() => Linking.openURL(arr[i].url)}
          style={{flex: 1}}>
        </TouchableOpacity>
      </ImageBackground>
      .....

When I click the image, I get this error:

undefined is not an object (evaluating 'arr[i].url')

I then verified that arr[i] etc. aren't undefined by:

console.log(arr[i])
console.log(arr[i].url)

and got correct values ('https://stackoverflow.com/' for this example).

When I hardcode the value to 'https://stackoverflow.com/', everything seems to work fine, which means there is an issue with the line Linking.openURL(arr[i].url) only. What exactly? I don't know :(

I've been stuck at this issue for quite some time, saw a few posts related to this, but nothing help. Can someone help me resolve this issue? Thanks...


Update:

I changed onPress={() => Linking.openURL(arr[i].url)} to:

onPress={() => Alert.alert(arr[i])}

and I got a completely blank alert!

Then, I did:

var x = arr[i].url

and changed the earlier line to:

onPress={() => Linking.openURL(x)}

Now, for all of the images, the link is set to arr[length-1].url, that is, its equal to the value of the url of the very last image in the array!

Upvotes: 1

Views: 3130

Answers (1)

ravibagul91
ravibagul91

Reputation: 20755

You can first check if app can handle this URL using canOpenURL

<TouchableOpacity
    onPress={() => Linking.canOpenURL(arr[i].url)
                     .then((supported) => {
                       if (!supported) {
                         console.log("Can't handle url: " + arr[i].url);
                       } else {
                         return Linking.openURL(arr[i].url);
                       }
                     })
                     .catch((err) => console.error('An error occurred', err));
    }
    style={{flex: 1}}>
      <ImageBackground
         source={{uri: arr[i].picUrl}}
         style={{ width: '100%',aspectRatio: 1, height: undefined }}>
      </ImageBackground>
</TouchableOpacity>

Update

Instead of for loop you can use map,

let views = arr.map(data => <View>
      <ImageBackground
        source={{uri: data.picUrl}}
        style={{ width: '100%',aspectRatio: 1, height: undefined }}>
        <TouchableOpacity
          onPress={() => Linking.openURL(data.url)}
          style={{flex: 1}}>
        </TouchableOpacity>
      </ImageBackground>
</View>
)

Upvotes: 2

Related Questions