skip to Main Content

I am trying to get an image to display if it exists, else display a default "Image not Available" image. As you can see I’m calling the imageExists function to see if an Image url returns true or false depending on whether it exists or not, and it does work. But in the ternary inside the Image uri, when the function returns false, simply no image at all appears, even though the "Image not Available" one should appear. Thanks for your help

import React from "react";
import {
  Text,
  View,
  StyleSheet,
  Button,
  TouchableHighlight,
  Image,
} from "react-native";

import { search } from "../mockData";

const imageExists = async (url) => {
  await fetch(url).then((response) => {
    console.log(response.ok);
    return response.ok;
  });
};

const HomeScreen = ({ navigation }) => {
  return (
    <View style={styles.container}>
      <Text>Home Screen</Text>
      <Image
        source={{
          uri: imageExists(search.Search[0].Poster)
            ? search.Search[0].Poster
            : "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/1024px-No_image_available.svg.png",
        }}
        style={{ width: 128, height: 128 }}
      />
      <Button
        title="Go to Details"
        onPress={() => navigation.push("Details")}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

export default HomeScreen;

2

Answers


  1. As Jurica mentioned, you need to do a bit of refactoring to make this work, as the imageExists is an async function.

    Here is a setup that might help you get started:

    const imageExists = async (url) => {
      const response = await fetch(url);
      return response.ok;
    };
    
    const HomeScreen = ({ navigation }) => {
    
      const [ imageUri, setImageUri ] = useState();
    
      useEffect(()=>{
        imageExists().then( ok =>{
            setImageUri( ok ? search.Search[0].Poster : "https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/1024px-No_image_available.svg.png" )
        })
      }, []);
    
      return (
        <View style={styles.container}>
          <Text>Home Screen</Text>
          <Image
            source={{ uri: imageUri }}
            style={{ width: 128, height: 128 }}
          />
          <Button
            title="Go to Details"
            onPress={() => navigation.push("Details")}
          />
        </View>
      );
    };
    

    Of course, you’ll need to think on how to handle the loading state, but this is just a boilerplate to help you get started.

    Login or Signup to reply.
  2. Use a async approach with the useEffect() or else create a separate function can call it inside the useEffect()

    const checkExistance = async (url) => {
      const response = await fetch(url);
      return response;
    };
    
    const HomeScreen = ({ navigation }) => {
    
      const [ imageUri, setImageUri ] = useState();
    
      useEffect(async()=>{
        try{
           const response = await checkExistance();
           if(response.status==='200'){
              setImageUri(response.URL);
           } else{
              setImageUri("https://url.com");
           }
        catch(e){
           console.log(e)
        }
    
      }, []);
    
      return (
        <View style={styles.container}>
          <Text>Home Screen</Text>
          <Image
            source={{ uri: imageUri }}
            style={{ width: 128, height: 128 }}
          />
          <Button
            title="Go to Details"
            onPress={() => navigation.push("Details")}
          />
        </View>
      );
    };
    

    Try Using try catch more. Easy to handle errors and issues when debugging

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search