react-native flatList renders blank screen - react-native-flatlist

I'm really new to react-native.
I'm trying to do a flatList.
At first it worked but then I added the bottom tab bar and then it didn't work anymore.
I tried to go back and delete the bottom tab bar but I always have an error.
The Last one was "can't find data". And now without changing anything, I just have a blank screen.
My code :
// Helpers/membersData.js
export default data = [
{
id:1,
name: "Name",
firstname: "Firstname",
address: "some address",
zipcode : 75000,
city: "city",
phone: "",
email: "name.e#gmail.com"
},
{
id:2,
name: "Othername",
firstname: "Otherfirstname",
address: "Other address",
zipcode : 75000,
city: "City",
phone: "0600000000",
email: "name.first#gmail.com"
}
]
The flatList :
// Components/Members.js
import members from '../Helpers/membersData';
import React from 'react';
import { StyleSheet, View, FlatList} from 'react-native';
import MemberDetails from './MemberDetails';
class Members extends React.Component {
render() {
return (
<View style={styles.main_container}>
<FlatList
keyExtractor={(item) => item.id.toString()}
data={members}
renderItem={({item}) => <MemberDetails member={item}/>}
/>
</View>
)
}
}
const styles = StyleSheet.create ({
main_container: {
marginTop: 25,
marginLeft: 10
}
})
export default Members
The list details
// Components/MemberDetails.js
import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
class MemberDetails extends React.Component {
render() {
const member = this.props.member
return (
<View style={styles.main_container}>
<View style={{flexDirection: 'row'}}>
<Text>{member.name}</Text>
<Text style={{marginLeft:10}}>{member.firstname}</Text>
</View>
<View >
<Text >{member.address}</Text>
</View>
<View style={{flexDirection: 'row'}} >
<Text >{member.zipcode}</Text>
<Text style={{marginLeft:10}}>{member.city}</Text>
</View>
<Text>{member.phone}</Text>
<Text style={{marginLeft:10}}>{member.email}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
height: 190,
flexDirection: 'column',
alignItems: 'center'
},
})
export default MemberDetails
The App.js
//import Members from './Components/Members'
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import Members from './Components/Members'
import Homepage from './Components/Homepage'
import SubscriptionsList from './Components/SubscriptionsList'
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Accueil" component={Homepage} />
<Tab.Screen name="Membres" component={Members} />
<Tab.Screen name="Abonnements" component={SubscriptionsList} />
</Tab.Navigator>
</NavigationContainer>
);
}
I don't know what I did wrong.
I'd really appreciate some help.
Thanks !

use
export default [
{
id:1,
name: "Name",
firstname: "Firstname",
address: "some address",
zipcode : 75000,
city: "city",
phone: "",
email: "name.e#gmail.com"
},
{
id:2,
name: "Othername",
firstname: "Otherfirstname",
address: "Other address",
zipcode : 75000,
city: "City",
phone: "0600000000",
email: "name.first#gmail.com"
}
]

Related

Why does my fetch request return 200 on pc but 400 on ios

I'm communicating to an API to update a state in my application. Everything works fine on PC. But on iOS the network request is 400 and the API does not return anything. Why? I'm running both through CORS anywhere and I've made sure to activate it both on my PC and my iOS device. One of the APIs that I'm communicating with in another file does work on both devices.
Home.js
import React, { useEffect, useState } from "react";
import { View, Text, SafeAreaView, ScrollView } from "react-native";
import { Divider } from "react-native-elements";
import BottomTabs from "../components/home/BottomTabs";
import Categories from "../components/home/Categories";
import HeaderTabs from "../components/home/HeaderTabs";
import RestaurantItems, {
localRestaurants,
} from "../components/home/RestaurantItems";
import SearchBar from "../components/home/SearchBar";
const YELP_API_KEY =
"x";
export default function Home({ navigation }) {
const [restaurantData, setRestaurantData] = useState(localRestaurants);
const [city, setCity] = useState("City");
const [activeTab, setActiveTab] = useState("Delivery");
const getRestaurantsFromYelp = () => {
const yelpUrl = `https://api.yelp.com/v3/businesses/search?term=restaurants&location=${city}`;
const corsUrl = `https://cors-anywhere.herokuapp.com/${yelpUrl}`;
const apiOptions = {
headers: {
Authorization: `Bearer ${YELP_API_KEY}`,
},
};
return fetch(corsUrl, apiOptions)
.then((res) => res.json())
.then((json) => {
console.log("JSON:", json.businesses);
setRestaurantData(json.businesses);
})
.catch((e) => console.log(e));
};
useEffect(() => {
getRestaurantsFromYelp();
}, [city, activeTab]);
useEffect(() => {
console.log("Restaurant Data Updated", restaurantData);
}, [restaurantData]);
return (
<SafeAreaView style={{ backgroundColor: "#eee", flex: 1 }}>
<View style={{ backgroundColor: "white", padding: 15 }}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar cityHandler={setCity} />
</View>
<ScrollView showsVerticalScrollIndicator={false}>
<Categories />
<RestaurantItems
restaurantData={restaurantData}
navigation={navigation}
/>
</ScrollView>
<Divider width={1} />
<BottomTabs />
</SafeAreaView>
);
}

React native app crashes when some components module are being imported

My index.ts file looks like as following:
import StaffMembers from './StaffMembers';
import GuestMembers from './GuestMembers';
export {
StaffMembers,
GuestMembers,
};
My folder structure looks like
This is my StaffMembers.tsx file :
import React from 'react';
import { AppDivider, CustomLabel } from '.';
import { View } from 'react-native-animatable';
import styles from '../styles';
import { Dropdown, TextInput, Label } from '../../../../components';
const StaffMembers: React.FC<{
member: string;
organisation: string;
orgLabel: string;
canDelete: () => void;
errors: any;
onDelete: () => void;
onValueUpdate: (updated: any) => void;
options: any[];
onDropdownStateChange: () => void;
zIndex: number;
onBlur: (fieldName: string) => void;
}> = ({
member,
organisation,
orgLabel,
canDelete,
errors = {},
onDelete = () => {},
onValueUpdate = () => {},
options = [],
zIndex = 1,
onBlur = () => console.log(),
}) => {
return (
<View style={[styles.listItem, { zIndex }]}>
<View style={{ flex: 1 }}>
<Dropdown
label={
canDelete ? (
<CustomLabel
title={<Label title='Staff Member' required />}
onDelete={onDelete}
/>
) : (
'Staff Member'
)
}
data={options}
onSelectItem={item => onValueUpdate({ member: item.value, ...item })}
errorMessage={errors.member}
value={member}
onBlur={() => onBlur('member')}
required
/>
</View>
<View style={{ flex: 1 }}>
<TextInput
disabled={true}
label={'Employee ID'}
value={organisation}
errorMessage={errors.organisation}
onChangeText={(val: string) => onValueUpdate({ organisation: val })}
/>
</View>
<AppDivider />
</View>
);
};
export default StaffMembers;
I'm importing components as
import { StaffMembers, GuestMembers } from '../request/components';
However when my app screen needs to load the component, it crashes giving the below error: Error when app crashes while loading component
When I edit the component's file and save it again, the app works fine.
Is there anything that I'm missing while importing the component? or something else?
The error clearly stat that you are not exporting the component/screen,
You are importing StaffMembers, GuestMembers which are modules, and not a class or component nested in the file, to solve this:
create index.js file in the root directory of ../request/components, and inside index.js file:
import StaffMembers from './StaffMembers';
import GuestMembers from './GuestMembers ';
export {
StaffMembers,
GuestMembers
};
now you can import the modules easily as you need.

Google SignIn for IOS with React-native (expo)

I'm setting up a page where I can Id with a Google account. This is my code:
import React from "react"
import { StyleSheet, Text, View, Image, Button } from "react-native"
import * as Google from "expo-google-app-auth";
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
signedIn: false,
name: "",
photoUrl: ""
}
}
signIn = async () => {
try {
const result = await Google.logInAsync({
androidClientId:
"1051966217196.apps.googleusercontent.com",
iosClientId:
"1051966217196.apps.googleusercontent.com",
scopes: ["profile", "email"]
})
if (result.type === "success") {
this.setState({
signedIn: true,
name: result.user.name,
photoUrl: result.user.photoUrl
})
} else {
console.log("cancelled")
}
} catch (e) {
console.log("error", e)
}
}
render() {
return (
<View style={styles.container}>
{this.state.signedIn ? (
<LoggedInPage name={this.state.name} photoUrl={this.state.photoUrl} />
) : (
<LoginPage signIn={this.signIn} />
)}
</View>
)
}
}
const LoginPage = props => {
return (
<View>
<Text style={styles.header}>Sign In With Google</Text>
<Button title="Sign in with Google" onPress={() => props.signIn()} />
</View>
)
}
const LoggedInPage = props => {
return (
<View style={styles.container}>
<Text style={styles.header}>Welcome:{props.name}</Text>
<Image style={styles.image} source={{ uri: props.photoUrl }} />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
},
header: {
fontSize: 25
},
image: {
marginTop: 15,
width: 150,
height: 150,
borderColor: "rgba(0,0,0,0.2)",
borderWidth: 3,
borderRadius: 150
}
})
On Android it's ok, everything is fine but in IOS I have that mistake :
Google 400 - That's an error - Error : redirect_uri_mismatch
Where is it goes wrong? I'm new to react native so I need detailed explanations.
I changed the bundle identifier to host.exp.exponent in Google credentials and it works. It's weird because I didn't change it in app.json. But it works.

Why react doesn't show Image from url local

hello every one I have an application running locally with RoR everything works fine in the backend, also I can see the Json in Postman
http://127.0.0.1:3000/api/v1/articles
[
{
"id": 1,
"title": "Barack Obama",
"description": "Sabias que? el era muy pobre",
"avatar_content_type": "/system/articles/avatars/000/000/001/original/user-two.png?1509755893"
}
]
and also in my mobile emulator I can see the Title and description that's mean everything works fine. BUT I can't see the image :/ some advice?
ProductList.js
// step 1: import libraries
import React, { Component } from 'react';
import { ScrollView } from 'react-native';
import Product from './Product';
export default class ProductList extends Component {
state = {
products: []
}
componentDidMount() {
return fetch('http://MYIP:3000/api/v1/articles')
.then((response) => response.json())
.then((responseJson) => {
this.setState({products: responseJson})
})
}
render() {
var productList = this.state.products.map(function(item) {
return (
<Product title = { item.title }
description = { item.description }
image_url = { item.avatar_content_type }
key = { item.id }/>
)
})
return (
<ScrollView>
{ productList }
</ScrollView>
);
}
}
Product.js
// step 1: import libraries
import React, { Component } from 'react';
import { StyleSheet, Text, View, Alert, Image } from 'react-native';
// step 2: create component
export default class Product extends Component {
render() {
return (
<View>
<Image source={{uri: this.props.image_url }} style={{width: 60,height: 60,}}/>
<Text style = { style.textStyle }>{ this.props.title }</Text>
<Text style = { style.textStyle }>{ this.props.description }</Text>
</View>
);
}
}
const style = StyleSheet.create({
textStyle: {
fontSize: 20,
padding: 20
},
amountStyle: {
fontSize: 15,
paddingLeft: 20
}
})
I dont get exceptions or something similar, I'm not just be able to see the Image in my mobile emulator
It may be because It is empty during the first render as you are trying to perform an asynchronous operation
So what you could do is u can check by giving a condition I normally do it with lodash using _.isEmpty method
try this:
<Image source={{uri: (_.isEmpty(this.props.image_url) ? null : this.props.image_url) }}

React native listview add item not working

I am new to react native and I was implemented a simple idea in my head. Basically, I am doing a 'todo list' like component which theres a add button below and items can be added. The problem arises after clicking on the add button and the list gets updated and the following xcode warning message appears. And I have realised, after implementing the ListView, that the app in the simulator slows down so much i couldn't even inspect. The alert popup would freeze the UI after some text are entered too, and the entire app needs to be built again since I couldn't do anything. Thanks for all the help!
Main component: SurveyQn
'use strict'
import React, {
Component,
StyleSheet,
Text,
TouchableHighlight,
TextInput,
View,
ListView,
AlertIOS
} from 'react-native';
var LongButton = require('./LongButton.js');
class SurveyQn extends Component {
constructor(props) {
super(props);
this.state = {
options: [{option: 'Pizza'}],
};
}
componentWillMount() {
this.dataSource = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
}
_renderItem(item) {
return (
<LongButton
text={item.option}
onPress={() => {}}
//btnViewStyle={styles.buttonView}
//btnTextStyle={styles.buttonText}
/>
);
}
_addItem() {
AlertIOS.alert(
'Add new option',
null,
[
{
text: 'Add',
onPress: (text) => {
var options = this.state.options;
options.push({option: text})
this.setState({ options: options})
}
},
],
'plain-text'
);
}
render(){
var dataSource = this.dataSource.cloneWithRows(this.state.options);
return (
<View style={styles.container}>
<TextInput
style={styles.question}
placeholder="Question title"
placeholderTextColor="#4B667B"
selectionColor="#4B667B"
onChangeText={(text) => this.setState({text})}/>
<View style={styles.listView}>
<ListView
dataSource={dataSource}
renderRow={this._renderItem.bind(this)}/>
</View>
<TouchableHighlight
onPress={this._addItem.bind(this)}
style={styles.buttonView}
underlayColor='rgba(0,0,0,0)'>
<Text style={styles.buttonText}>
Add option
</Text>
</TouchableHighlight>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
width: 300,
flex :1,
},
listView: {
flex: 1,
},
question: {
height: 30,
fontSize: 20,
fontWeight: "100",
color: '#4B667B',
marginTop: 10,
marginBottom: 10,
},
buttonView: {
width: 300,
paddingVertical: 9,
borderWidth: 1,
borderColor: '#F868AF',
marginBottom: 13,
},
buttonText: {
textAlign: 'center',
fontSize: 25,
color: '#F868AF',
fontWeight: '500'
},
});
ListView item: LongButton
'use strict'
import React, {
Component,
StyleSheet,
Text,
TouchableHighlight,
View,
} from 'react-native';
class LongButton extends Component {
render(){
return (
<TouchableHighlight
onPress={this.props.onPress}
style={this.props.btnViewStyle}
underlayColor='rgba(0,0,0,0)'>
<Text style={this.props.btnTextStyle}>
{this.props.text}
</Text>
</TouchableHighlight>
);
}
}
module.exports = LongButton;
Xcode warning message upon adding item on alert
app[27881:11151280] the behavior of the UICollectionViewFlowLayout is not defined because:
app[27881:11151280] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
app[27881:11151280] The relevant UICollectionViewFlowLayout instance is <_UIAlertControllerCollectionViewFlowLayout: 0x7ff0685b1770>, and it is attached to ; layer = ; contentOffset: {0, 0}; contentSize: {0, 0}> collection view layout: <_UIAlertControllerCollectionViewFlowLayout: 0x7ff0685b1770>.
2016-04-06 07:50:01.545 decisionapp[27881:11151280] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
Updates:
I tried this but its not working either. Could it be the alert causing these problems? Its just taking forever to render the alert after clicking on the btn.
class SurveyQn extends Component {
constructor(props) {
super(props);
this.state = {
options: [{option: 'Pizza'}],
dataSource : new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
};
}
componentWillMount() {
var data = this.state.options;
this.state.dataSource.cloneWithRows(data);
}
_renderItem(item) {
return (
{item.option}
);
}
_addItem() {
AlertIOS.alert(
'Add new option',
null,
[
{
text: 'Add',
onPress: (text) => {
var options = this.state.options;
options.push({option: text})
this.setState({ options: options})
}
},
],
'plain-text'
);
}
render(){
return (
<View style={styles.listView}>
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderItem.bind(this)}/>
</View>
<TouchableHighlight
onPress={this._addItem.bind(this)}
style={styles.buttonView}
underlayColor='rgba(0,0,0,0)'>
<Text style={styles.buttonText}>
Add option
</Text>
</TouchableHighlight>
</View>
);
}
}
Before diving into complex EcmaScript notation, you can use simple notation. Here is a simple example of ListView. Please go through it and understand how it works.
var API = require('./API');
module.exports = React.createClass({
getInitialState: function(){
return {
rawData: [],
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
}),
loaded: false,
}
},
componentWillMount: function(){
this.loadData();
},
loadData: function(){
API.getItems()
.then((data) => {
this.setState({
rawData: this.state.rawData.concat(data),
dataSource: this.state.dataSource.cloneWithRows(data),
loaded: true,
});
});
},
render: function(){
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderItem}
style={styles.listView}>
</ListView>
);
},
renderItem: function(item){
return (
<View>
<Text>Custom Item</Text>
</View>
);
},
}
In API.js, I am fetching data from an API.
getItems: function(){
var REQUEST_URL = 'http://api.example.org/item/get?api_key=xxxx;
return fetch(REQUEST_URL)
.then((response) => response.json())
.then((responseData) => {
return responseData.results.sort(sortByDate);
});
}
The code may not work, since I have not tested. But you can refer my sample project on github. Repo

Resources