I am grabbing data from an API to display an image based on the API value. The following code works perfect IF there is an image in the object. If an API item does not have an image the app throws an "Undefined is not an object" error.
<View>
<Image source={{uri:props.enclosures[0].url}} style={styles.mainPhoto} />
</View>
I have tried the following code to check if the value exists first, but it still throws exact same error if an API item does not have image.
<View>
{props.enclosures[0].url ?
<Image source={{uri:props.enclosures[0].url}} style={styles.mainPhoto} />
:
<Text>No Image</Text>
}
</View>
If you are going to access multiple properties of a nested object, you should check everything, like so
<View> // Checking everthing so it never throws an error
{props.enclosures && props.enclosures[0] && props.enclosures[0].url ?
<Image source={{uri:props.enclosures[0].url}} style={styles.mainPhoto} />
:
<Text>No Image</Text>
}
</View>
To prevent undefined error you can also use path from Ramda library. It allows you to safely access any nested object/array.
const MyComponent = (props) => {
const apiImage = path(["enclosures", 0, "url"], props);
return {
<View>
{apiImage ?
<Image source={{uri:apiImage}} style={styles.mainPhoto} />
:
<Text>No Image</Text>
}
</View>
}
}
Related
Im trying to map my state , but it allways returns me this error, someone knows how to solve it ?
useEffect(() => {
if (mounted && userForm.length > 0) {
console.log(userForm, 'campos:', userForm.fields);
return;
} else {
setuserForm(JSON.parse(route.params.paramKey));
console.log(userForm);
}
}, [userForm]);
return (
<SafeAreaView style={{flex: 1}}>
<View style={styles.container}>
<Text style={styles.textStyle}>COLLECTION :</Text>
{userForm.length > 0 ? (
userForm.map((item) => (
<Text key={uuid.v4()}>{item.fields}</Text>
))
) : (
<Text key={uuid.v4()}> Loading ...</Text>
)}
</View>
</SafeAreaView>
);
};
what I'm trying to do is render all my fields and then handle the following types.
If I understand you correctly, you are trying to render item.field as node. However, seems that this is an array, so you need to map it one more time.
For example, if it contains strings it might looks like this:
<Text key={uuid.v4()}>{item.fields?.concat('')}</Text>
In case filds contains objects you have to map it to the new component, like this:
<Text key={uuid.v4()}>{item.fields?.map((field, i)=> <div key={i}>{field.someProp}</div>}</Text>
In case you don't know what is inside the fields, check the Network tab in the ChromeDeveloperTools (F12) or use JSON.stringify
I have a problem understanding why this code isnt working.
If i use it like this:
const [theInfo , setTheInfo] = useState(null);
return (
theInfo ?(
...):(
...)
Its working without any problems. But as soon as i add a View or anything above or after theInfo... like this:
const [theInfo , setTheInfo] = useState(null);
return (
<View>
<View>
<Text>Hi</Text>
</View>
theInfo ?(
...):(
...)
</View>
Then I get this error: TypeError: null is not an object (evaluating 'theInfo.map')
I dont understand why this is happening. I want to set a searchbar on top, and after this the theInfo?(... part
theInfo is a variable, you can't use it jsx in such a way, inclose it in curly braces :
const [theInfo , setTheInfo] = useState(null);
return (
<View>
<View>
<Text>Hi</Text>
</View>
{
theInfo ?(
...):(
...)
}
</View>
enter image description hereWhen using navigation v5, I encounter an error can not read property navigate of undefined
const Categories=({navigation})=> {
return (
<View >
<Text style={Styles.TextCategories}>دسته بندی ها</Text>
{/* ---------------------------------------------------------------لایه کلی صفحه---------------------------------- */}
<View style={Styles.View}>
{/* --------------------------------------------------------------- لایه دکمه ها---------------------------------- */}
<Button style={Styles.Button} onPress={()=>navigation.navigate('Homesales')}>
<MaterialIcons name="waves" size={30} color={"#0c7656"} />
<Text style={Styles.Text}>زمین</Text>
</Button>
const Home=()=>{
useEffect(()=>{
axios.get('https://jsonplaceholder.typicode.com/posts').then((response)=>console.log(response.data)).catch((e)=>console.log(e))
},[])
return (
<Categories/>
);
}
export default React.memo(Home);
why don't you use navigation hook of react-navigation-v5?? instead of passing navigation as prop try to "useNavigation()" hook, this way you will have access to a valid navigation object from anywhere
const navigation=useNavigation()
for using navigation
navigation.navigate('')
You are passing a object that does not has property 'navigation' to component Categories
You need to check at the parent component, seem that props/navigation is null here.
I am learning React-Native and using react-native-snap-carousel in my project.
I want to show some images but I got error Cannot read property 'concat' of undefined.
Here is my code.
const HomePage = (props) => {
let imageList = ['../images/index-bg.png', '../images/down.png'];
const renderImage = ({ item, index }) => {
return (
<View>
<Image source={require(item)}></Image>
</View>
)
};
return (
<View>
<Carousel
loop={true}
autoplay={true}
data={imageList}
renderItem={renderImage}
sliderWidth={pxToDp(50)}
itemWidth={pxToDp(100)}
/>
</View>
)
}
If I change
<View>
<Image source={require(item)}></Image>
</View>
to
<View>
<Image source={'../images/index-bg.png'}></Image>
</View>
···
it works well
I expect it would work like [Usage](https://github.com/archriss/react-native-snap-carousel) but it doesn't work.
Did you try this?
let imageList = [require('../images/index-bg.png'), require('../images/down.png')];
and then
<View>
<Image source={item}></Image>
</View>
Required source for images in RN have to be defined before runtime
Let me know if it works!
Just started learning React native and have been using Udemy to get the hang of things and this error has me stumped. I followed the tutorial to the letter.
getInitialState:function(){
return {
timeElapsed:null
}
},
render:function(){
return (
<View style={styles.container}>
<View style ={[styles.header,this.border('yellow')]}>
<View style={[styles.timerWrapper,this.border('red')]}>
<Text>
{this.state.timeElapsed}
</Text>
</View>
<View style={[styles.buttonWrapper,this.border('green')]}>
{this.startStopButton()}
{this.lapButton()}
</View>
</View>
<View style={[styles.footer, this.border('blue')]}>
<Text>
I am a list of laps
</Text>
</View>
</View>
);
},
startStopButton: function(){
return (
<TouchableHighlight underlayColor="green"
onPress={this.handleStartPress}>
<Text>
Starts
</Text>
</TouchableHighlight>
);
}
The error message states that I am trying to return more than 1 object from getInitialState function. From the examples I could find online, this seems to be the correct format. What am I missing here.
The entire error message is: Objects are not valid as a React child. If you meant to render a collection of children, use an array instead or wrap the object using createFragment.
I think the code below caused the error, this.state.timeElapsed must be a React-Node. You may return a javascript object in timeElapsed, something like Date instance.
<Text>
{this.state.timeElapsed}
</Text>
If you don't sure what is React-Node, you can read the official docs about that here.