0

I'm a beginner to development and I'm getting Undefined is not an object error. What am I doing wrong here? When I console log placeID it returns value, but selectedPlace returns undefined. Thanks.

const PlaceDetailScreen = props => {
  const [places, setPlaces] = useState([])

  useEffect(() => {
    const getPlaces = async () => {
      const result = await axios.get('https://tgr-admin.appspot.com/api/places')

      setPlaces(result.data)
    }

    getPlaces()
  }, [])

  const placeID = props.navigation.getParam('placeId')

  const selectedPlace = places.find(place => place._id === placeID)

  return (
    <ScrollView>
      <Image source={{ uri: selectedPlace.image }} style={styles.image} />
    </ScrollView>
  )
}
0

2 Answers 2

3

The issue is with the selectedPlace, before getPlaces complete, the places is an empty array and .find method returns undefined. Accessing an image prop on selectedPlace undefined throws an error. Perform null check before accessing the image prop on selectedPlace.

const PlaceDetailScreen = props => {
  const [places, setPlaces] = useState([])

  useEffect(() => {
    const getPlaces = async () => {
      const result = await axios.get('https://#')

      setPlaces(result.data)
    }

    getPlaces()
  }, [])

  const placeID = props.navigation.getParam('placeId')

  const selectedPlace = places.find(place => place._id === placeID)
  // selectedPlace is undefined and places equals []
  // perform null check before accessing image prop
  return (
    <ScrollView>
      <Image source={{ uri: selectedPlace && selectedPlace.image }} style={styles.image} />
    </ScrollView>
  )
}

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

2 Comments

It worked, thank you very much, you're great. :) Also I'd like to ask 1 more question if you have time. When I use filter method instead of find, it returns an array. But when I console log selectedPlace.image it is undefined. What is the reason for that? Thank you very much again.
filter method return array of filtered objects, so access first array element then access image prop, like this selectedPlace[0] && selectedPlace[0].image
0

Based on Aadil Mehraj's answer, wrapping the content with null check also works. So I can add more stuff inside.

  return (
    <ScrollView>
      {selectedPlace && (
        <>
          <Image source={{ uri: selectedPlace.image }} style={styles.image} />

          <View style={styles.container}>
            <MarkdownView styles={markdownStyles}>
              {selectedPlace.content}
            </MarkdownView>
          </View>

        </>
      )}
    </ScrollView>
  )
}

Comments

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.