Error in non-iPhoneX devices - null is not an object - ios

When I run my app on a iPhone X simulator, it works as designed with no errors.
When I run it on an iPhone 5S, 7, and all other non iPhone X devices, I get an error that says, null is not an object (evaluating '_this.props.filters.map)
This is the render part of my code:
render() {
return(
<View>
<NativeText
color='gray'
style={{
paddingLeft: '3%',
paddingTop: '2%',
paddingBottom: '2%',
borderBottomColor: 'gray',
borderBottomWidth: 1,
fontSize: 14
}}>Saved Filters</NativeText>
<View
style={{
borderBottomColor: 'gray',
borderBottomWidth: 1,
}}
/>
<View style={{flexDirection: 'row', flexWrap: 'wrap', backgroundColor: '#f7fafc'}}>
{
this.props.filters !== null ? this.props.filters.map(
(v, i) => {
return(
<View key={i} style={{flexDirection:'row', alignItems:'center', paddingLeft: '2%'}}>
<NativeText
key={i}
onPress={() => this.updateCurrentFilter(i)}
style={{
paddingLeft: 10,
fontWeight: "100",
fontSize: 14
}}
>{v.filter_name} </NativeText>
<View
style={{
alignSelf: 'flex-end'
}}
>
<Icon
name={this.props.checkedFilters !== undefined && this.props.checkedFilters[i] === true ? 'toggle-switch' : 'toggle-switch-off-outline'}
size={29}
style={{top: '7%'}}
color='black'
onPress={() => this.updateCurrentFilter(i)}
/>
</View>
</View>
)
}
) : null
}
</View>
<View
style={{
borderBottomColor: 'gray',
borderBottomWidth: 1,
}}
/>
</View>
)
}
The props comes from a redux reducer with a default state of null.
Is there anything specific to non-iPhone X devices that I should be aware of?

You are getting error because this.props.filters has null value in it
try this :
<View style={{flexDirection: 'row', flexWrap: 'wrap', backgroundColor: '#f7fafc'}}>
{
this.props.filters ?
this.props.filters.length > 0 ?
this.props.filters.map((v, i) => {
return(
</View> // your component here
)})
: null
: null
}
</View>

Related

React Native Flatlist shows a blank space in tvOS

I'm trying to show a flatList in tvOS and when the flatlist is rendered it shows unwanted space at the top of the rendered items inside the flatlist. This issue is not happening in Android TV or Fire TV.
My code :
<SafeAreaView
style={{
flex: 1,
backgroundColor: Colors.APP_BACKGROUND,
flexDirection: 'row',
}}>
<View style={{width: '27%'}}>
<View
style={[{flex: 1, marginLeft: Platform.OS === 'android' ? '10%' : '5%', marginRight: '10%', marginTop: '10%'}]}>
<Text
style={[
{
fontSize: FontSize.large,
color: Colors.WHITE,
fontFamily: FontFamily.bold,
marginBottom: '5%',
paddingHorizontal: ms(10),
marginLeft: Platform.OS === 'android' ? ms(5) : ms(2),
},
]}>
Settings
</Text>
<FlatList
data={pages}
renderItem={({item, index}) => renderSettingItem(item, index)}
removeClippedSubviews={false}
/>
</View>
</View>
<View
style={{
backgroundColor: Colors.SEPARATOR_SETTING_PAGE,
width: 3,
marginTop: '2%',
height: '60%',
}}
/>
<View style={{width: '73%'}}>
<SettingPageComponent page={page} />
</View>
</SafeAreaView>
I don't know what I did wrong. I'd really appreciate some help. Thanks !

React Native RefreshControl in iOS shows a white line when pulling down

in iOS, a white line will appear when pulling up the <ScrollView> with refreshControl, anyone knows the reasons?
<ScrollView
removeClippedSubviews={true}
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl
refreshing={props.listViewState.pullToRefresh}
onRefresh={handleOnRefresh}
/>
}
contentContainerStyle={{backgroundColor: 'white'}}
>
<View> ... </View>
<View> ... </View>
</ScrollView>
white line appears
I had the same issue with Flatlist.
Try something like this.
return (
<SafeAreaView style={styles.container}>
<View style={styles.container2}/>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
contentContainerStyle={{ backgroundColor: 'white' }}
ListHeaderComponent={<View>
<Text style={{backgroundColor:'#293541'}}>HEADER</Text></View>}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
tintColor={'red'}
backgroundColor={'#293541'}
/>
}
/>
</SafeAreaView>
);
and for styling :
container: {
flex:1,
marginTop: StatusBar.currentHeight || 0,
backgroundColor: 'white',
},
container2: {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '60%',
backgroundColor: '#293541',
},

React Native SyntaxError ","

Receiving syntax error, SyntaxError: Unexpected token, expected ",". It is for the third to last line ");"
I am having trouble seeing where I need to insert the ",". I have tried in front of the ); and after. No luck. This is while I was adding the code for google sign in for ios. Would appreciate any assistance.
render() {
LayoutAnimation.easeInEaseOut();
const scrollEnabled = this.state.screenHeight > height;
return (this.state.logedin ?
<View style={styles.container}>
<StatusBar barStyle="light-content"></StatusBar>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={styles.scrollview}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<ImageBackground source={require("/Users/carloscraig/NoExcusasRN/screens/assets/grassbcg2.png")}
style={{ width: '100%', height: '100%' }}>
<Image source={require("/Users/carloscraig/NoExcusasRN/screens/assets/noexlogo.png")}
style={styles.logo}>
</Image>
<Text style={styles.greeting}>{'BIENVENIDO!'}</Text>
<View style={styles.errorMessage}>
{this.state.errorMessage && <Text style={styles.error}>{this.state.errorMessage}</Text>}
</View>
<View style={styles.form}>
<View>
<Text style={styles.inputTitle}>correo electrónico</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={email => this.setState({ email })}
value={this.state.email}
></TextInput>
</View>
<View style={{ marginTop: 32 }}>
<Text style={styles.inputTitle}>contraseña</Text>
<TextInput
style={styles.input}
secureTextEntry
autoCapitalize="none"
onChangeText={password => this.setState({ password })}
value={this.state.password}
></TextInput>
</View>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleLogin}>
<Text style={{ color: "#FFF", fontWeight: "500" }}>Iniciar Sesión</Text>
</TouchableOpacity>
<SafeAreaView style={{
flex: 1,
justifyContent: 'center'
}}>
<Image style={{
width: 300,
height:300,
justifyContent: 'center',
alignSelf: 'center'
}} source={{uri: this.state.photo}} />
<Text>{this.state.name}</Text>
<Text>{this.state.email}</Text>
</SafeAreaView>:
<SafeAreaView style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Light}
onPress={this._signIn}
disabled={this.state.isSigninInProgress} />
</SafeAreaView>
<TouchableOpacity
style={{ alignSelf: "center", marginTop: 32 }}
onPress={() => this.props.navigation.navigate("Register")}
>
<Text style={{ color: "#414959", fontSize: 13 }}>
No tienes una Cuenta? <Text style={{ fontWeight: "500", color: "#E9446A" }}>Regístrate</Text>
</Text>
</TouchableOpacity>
</ImageBackground>
</ScrollView>
</View>
);
}
}
React conditional rendering
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn
? <LogoutButton onClick={this.handleLogoutClick} />
: <LoginButton onClick={this.handleLoginClick} />
}
</div>
);
}
You need to add the other half (false case) to the ternary. In this case if you do not want to render anything you need to return null.
render() {
LayoutAnimation.easeInEaseOut();
const scrollEnabled = this.state.screenHeight > height;
return (this.state.logedin ?
<View style={styles.container}>
<StatusBar barStyle="light-content"></StatusBar>
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={styles.scrollview}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<ImageBackground source={require("/Users/carloscraig/NoExcusasRN/screens/assets/grassbcg2.png")}
style={{ width: '100%', height: '100%' }}>
<Image source={require("/Users/carloscraig/NoExcusasRN/screens/assets/noexlogo.png")}
style={styles.logo}>
</Image>
<Text style={styles.greeting}>{'BIENVENIDO!'}</Text>
<View style={styles.errorMessage}>
{this.state.errorMessage && <Text style={styles.error}>{this.state.errorMessage}</Text>}
</View>
<View style={styles.form}>
<View>
<Text style={styles.inputTitle}>correo electrónico</Text>
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={email => this.setState({ email })}
value={this.state.email}
></TextInput>
</View>
<View style={{ marginTop: 32 }}>
<Text style={styles.inputTitle}>contraseña</Text>
<TextInput
style={styles.input}
secureTextEntry
autoCapitalize="none"
onChangeText={password => this.setState({ password })}
value={this.state.password}
></TextInput>
</View>
</View>
<TouchableOpacity style={styles.button} onPress={this.handleLogin}>
<Text style={{ color: "#FFF", fontWeight: "500" }}>Iniciar Sesión</Text>
</TouchableOpacity>
<SafeAreaView style={{
flex: 1,
justifyContent: 'center'
}}>
<Image style={{
width: 300,
height: 300,
justifyContent: 'center',
alignSelf: 'center'
}} source={{ uri: this.state.photo }} />
<Text>{this.state.name}</Text>
<Text>{this.state.email}</Text>
</SafeAreaView>:
<SafeAreaView style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}>
<GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Light}
onPress={this._signIn}
disabled={this.state.isSigninInProgress} />
</SafeAreaView>
<TouchableOpacity
style={{ alignSelf: "center", marginTop: 32 }}
onPress={() => this.props.navigation.navigate("Register")}
>
<Text style={{ color: "#414959", fontSize: 13 }}>
No tienes una Cuenta? <Text style={{ fontWeight: "500", color: "#E9446A" }}>Regístrate</Text>
</Text>
</TouchableOpacity>
</ImageBackground>
</ScrollView>
</View>
: null);
}

Iphone 5 status bar is being covered React Native

My code works fine on Most of iPhones but on Iphone 5 the status bar has been covered by the view, I don't know how to margin the view in Iphone 5 only if i used margin top in the view, it looks weird in other iPhones
componentWillMount() {
this.startHeaderHeight = 45
this.marginTopHeader = 0
this.iconMargin = 9
if (Platform.OS == 'android') {
this.startHeaderHeight = 30 + StatusBar.currentHeight
this.marginTopHeader = 23 + this.marginTopHeader
this.iconMargin = this.iconMargin
}
}
render() {
var width = Dimensions.get('window').width - 128;
var height = Dimensions.get('window').height;
return (
<SafeAreaView style={{
height: this.startHeaderHeight, flexDirection: 'row',
borderBottomColor: '#ddd', backgroundColor: '#3A3658', marginTop: this.marginTopHeader
}} >
<Icon
lightTheme
style={{ marginLeft: 8, marginRight: 5, marginTop: this.iconMargin, color: 'white' }} size={25} name="ios-menu" onPress={() => {
this.props.draw();
}} />
<View style={{position: 'absolute', right: 7}}>
<Icon style={{ color: '#fff',marginTop: this.iconMargin ,padding:0,}} size={25} name="ios-cart" onPress={() => {
this.props.cart();
}}>
<Text style={{color:'red', fontWeight:'bold', fontSize:10}}>{this.props.cartItemCount}</Text>
</Icon>
</View>
</SafeAreaView >
You can try to write like this.
<View style={{flex: 1, backgroundColor: 'white'}} >
{/* header */}
<View style={{paddingTop: system.ios.x ? 22 : 0}}>
<View style={{
height: Platform.select({ios: 64, android: 44}),
backgroundColor: 'white',
justifyContent: 'flex-end'
}}>
`enter code here`
</View>
</View>
</View>

React Native KeyboardAvoidingView not working properly

I am trying to use the KeyboardAvoidingView with behavior="padding".
When I am trying to enter any text in TextInput, the TextInput field is not moving up. I have added a small view in the end which is moving up but the the view above it.
I have also with KeyboardAvoidingView height property with offset. It was working few components like 2 TextInputs. But when I add all the components the UI goes insane and behave jumbled up.
Any any idea whats happening over here?
Here the link of tutorial which I have followed.
render() {
return (
<View style={styles.backgroundContainer}>
<Loader
loading={this.state.isLoading} />
<KeyboardAvoidingView
keyboardVerticalOffset={10}
style={styles.mainContainer}
behavior='padding' >
<View style={styles.formContainer}>
<View style={[styles.centerContainer, { marginTop: 40 }]}>
<Image source={require('./../../Resources/logo.png')} />
<Text style={{ fontWeight: 'bold', color: 'gray', fontSize: 25 }}>AppName</Text>
<Text style={styles.loginMsg}> Login to your Account </Text>
</View>
<View style={styles.inputFieldsContainer}>
<Image style={{ width: 30, height: 30, margin: 5 }} source={require('./../../Resources/logo.png')} />
<TextInput
placeholder='Email'
returnKeyType='next'
keyboardType='email-address'
onChangeText={(value) => this.setState({ userEmail: value })}
onSubmitEditing={() => this.passwordInput.focus()}
style={styles.inputFields} />
</View>
<View style={styles.inputFieldsContainer}>
<Image style={{ width: 30, height: 30, margin: 5, }} source={require('./../../Resources/logo.png')} />
<TextInput
returnKeyType='go'
secureTextEntry
placeholder='Password'
ref={(input) => this.passwordInput = input}
onChangeText={(value) => this.setState({ password: value })}
style={styles.inputFields} />
</View>
<View style={styles.buttonContainer}>
<Button
fontSize='8'
color='gray'
title='Remember Me'
onPress={() => {
console.log('Remember Me Clicked');
}} />
<Button
color='gray'
title='Forgot Password?'
onPress={() => {
console.log('Forgot Password Clicked');
}} />
</View>
<TouchableOpacity
style={styles.buttonLogin}
onPress={() => {
console.log('Login Clicked');
}}
>
<Text style={{ fontSize: 20, fontWeight: 'bold', color: 'white' }}>Login</Text>
</TouchableOpacity>
<View style={{ height: 1, backgroundColor: 'gray', marginTop: 20, marginBottom: 1 }}>
</View>
<View style={[styles.centerContainer, { marginBottom: 10 }]}>
<Text style={styles.loginMsg}>Don't have a Account</Text>
<TouchableOpacity
style={styles.buttonRegister}
onPress={() => navigate('Register')} >
<Text style={styles.buttonRegisterText}>REGISTER NOW</Text>
</TouchableOpacity>
</View>
</View>
<View style={{ height: 10, backgroundColor: '#628499', }}>
</View>
</KeyboardAvoidingView>
</View>
);
}
const styles = StyleSheet.create({
backgroundContainer: {
flex: 1, backgroundColor: 'green'
},
mainContainer: {
flex: 1, margin: 25,
borderWidth: 1, borderRadius: 5, borderColor: 'gray',
backgroundColor: 'white',
justifyContent: 'space-between'
},
formContainer: {
flex: 1, paddingLeft: 25, paddingRight: 25
},
centerContainer: {
alignItems: 'center', marginBottom: 10,
},
loginMsg: {
margin: 10,
fontSize: 20, color: 'gray'
},
inputFieldsContainer: {
flexDirection: 'row', margin: 10,
borderWidth: 1, borderRadius: 5, borderColor: 'gray',
},
inputFields: {
flexGrow: 1,
marginTop: 5, marginBottom: 5,
height: 30,
backgroundColor: 'rgba(255,255,255,0.4)',
paddingHorizontal: 10,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between'
},
buttonLogin: {
alignItems: 'center', height: 40, marginTop: 10, marginLeft: 50, marginRight: 50, padding: 5,
backgroundColor: '#2980b9',
borderWidth: 1, borderRadius: 5, borderColor: 'gray'
},
buttonRegister: {
alignItems: 'center', height: 40,
marginLeft: 50, marginRight: 50
},
buttonRegisterText: {
fontSize: 20, fontWeight: 'bold', color: 'gray'
},
loading: {
position: 'absolute',
left: 0, right: 0, top: 0, bottom: 0,
alignItems: 'center', justifyContent: 'center'
}, });
I used KeyboardAvoidingView, it also doesn't work.
I found this solution, You can take the base code.
Installation
npm i react-native-keyboard-aware-scroll-view --save
Usage
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
<KeyboardAwareScrollView>
<View>
<TextInput />
</View>
</KeyboardAwareScrollView>
You can find it here
The way it worked for me was to use position as behavior and -70 as vertical offset. Any non negative integer was creating a huge unused space when the keyboard pops up.
<KeyboardAvoidingView
style={styles.container}
behavior={Platform.OS === 'ios' ? 'position' : 'height'}
keyboardVerticalOffset={Platform.OS === 'ios' ? -70 : 70}
enabled>
<ScrollView>
...
</ScrollView>
</KeyboardAvoidingView>
<KeyboardAvoidingView
style={styles.mainContainer}
behavior="padding"
enabled
>
<View>.......................</View>
</KeyboardAvoidingView>
'Enabled or disabled KeyboardAvoidingView' should be add.
Keep in mind is always your top Parent with flex:1 then the child is then you text input container
<KeyboardAvoidingView style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "position" : null} enabled>
<ScrollView>
<View>
<View >
<Text maxFontSizeMultiplier={1.5} >
Sign in to your account{" "}
</Text>
<View
behavior="padding"
enabled
>
<TextInput
placeholder="Email address"
placeholderTextColor={Colors.grey}
style={styles.textInput}
onChangeText={(e) => setEmail(e.trim())}
autoCapitalize="none"
returnKeyType={"done"}
/>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>
// 2nd Solutions use this package
npm i react-native-keyboard-aware-scroll-view --save
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
<KeyboardAwareScrollView>
<View>
<TextInput />
</View>
</KeyboardAwareScrollView>

Resources