React Native Flatlist Touchable opacity - react-native-flatlist

I'm new to programming and I can't seem to add touchable opacity to flatlist renderitem for contacts. anyone can help?
I need this code to have a touchable opacity
import React, {useEffect, useState} from 'react';
import {FlatList, View, Text, StyleSheet,TouchableOpacity} from 'react-native';
import Contacts from 'react-native-contacts';
import {Contact} from '.';
const ContactsList = () => {
const [contacts, setContacts] = useState([]);
useEffect(() => {
Contacts.getAll().then(contacts => {
setContacts(contacts);
});
}, []);
const keyExtractor = (item, idx) => {
return item?.recordID?.toString() || idx.toString();
};
const renderItem = ({item, index}) => {
return <Contact contact={item} />;
};
return (
<FlatList
data={contacts}
keyExtractor={keyExtractor}
style={styles.list}
renderItem={ renderItem }
/>
);
};
const styles = StyleSheet.create({
list: {
flex: 1,
},
});
export default ContactsList;

Related

React Native NOT rendering data from database on IOS

I have problem with render data on IOS Simulator. Render is work properly on website, but on IOS I still got stuck on "Loading.." text.
Here is my code:
import React from 'react'
import { useState } from 'react';
import { useEffect } from 'react';
import { SafeAreaView, Text, View, StyleSheet, Image, Alert } from 'react-native';
import { Card } from 'react-native-paper'
import firebase from 'firebase'
import Button from '../components/Button'
import Background from '../components/Background'
import TopBar from '../components/TopBar'
export default function HomeScreen({ navigation }) {
const [data, setData] = useState([])
const sampleData = [{id:0, title:"One"}, {id:1, title: "Two"}]
useEffect(() =>
{
const donorsData = [];
firebase.database()
.ref("testdb")
.orderByChild("isDonor")
.equalTo(true)
.once("value")
.then((results) => {
results.forEach((snapshot) => {
donorsData.push(snapshot.val());
});
setData(donorsData);
});
}, [])
const card = data.length > 0
? data.map(item =>
{
return <Card key={item.uid} style={{ marginBottom: 20, borderRadius: 10, }}>
<Text>{item.name}</Text>
<Text>{item.description}</Text>
<Image src={item.photo}></Image>
</Card>
})
: <Text>Loading...</Text>
return (
<View style={styles.container}>
{card}
</View>
);
}
On website is everything ok Website Screen
But on IOS Simulator I got only Loading
IOS Screen
I tried a lot of solutions found here, but no one works with this case. I think is probably because iOS doesn't have data? When I put console log at to top of return, I got nothing.
This might be a race condition error. You shouldn't rely on the data being fetched within 1500ms.
If that doesn't work. Make sure your result from firebase is correct.
Maybe something like this?
const [data, setData] = useState([])
const fetchDonorData = () => {
firebase.database()
.ref("testdb")
.orderByChild("isDonor")
.equalTo(true)
.once("value")
.then((results) => {
console.log({result}) //Make sure the data looks the way you want it
const mappedResult = results?.map(snapshot => snapshot.val())
setData(mappedResult)
})
}
useEffect(() => {
fetchDonorData()
}, [])
const renderItem = ({item}) =>
<Card style={{ marginBottom: 20, borderRadius: 10, }}>
<Text>{item.name}</Text>
<Text>{item.description}</Text>
<Image src={item.photo}></Image>
</Card>
return (
<View style={styles.container}>
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={({item}) => item.uid}
ListEmptyComponent={<Text>Loading...</Text>}
/>
</View>
)

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 View-pager setPage is not working on iOS

I'm using react-native-pager-view and I try to setPage on my index change but it doesn't work on iOS devices. Flow is like this that I try to pass the index as a props to my custom ViewPager and I'm using the UseEffect to setPage for my ViewPager which is not working on iOS and I have no idea why.
// #flow
import React, { useEffect, useRef } from 'react';
import { StyleSheet, View, I18nManager } from 'react-native';
import PagerView, { PagerViewOnPageSelectedEvent } from 'react-native-pager-view';
type Props = {
children: React$Node,
index: number,
onIndexChange: (index: number) => void,
};
const MyViewPager = ({ children, index, onIndexChange }: Props) => {
const viewPagerRef = useRef<PagerView>(null);
useEffect(() => {
viewPagerRef.current?.setPage(index);
}, [index]);
const onPageSelect = (e: PagerViewOnPageSelectedEvent) => {
onIndexChange(e.nativeEvent.position);
};
return (
<View style={styles.container}>
<PagerView
ref={viewPagerRef}
style={styles.container}
initialPage={index}
orientation="horizontal"
onPageSelected={onPageSelect}
>
{children}
</PagerView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default MyViewPager;
the #next version "^6.0.0-rc.0" worked for me
yarn add react-native-pager-view#^6.0.0-rc.0
or if you are using npm
npm i react-native-pager-view#^6.0.0-rc.0
If you have layoutDirection="rtl" prop in PagerView.
Try Removing it e.g
Not working code
<PagerView
initialPage={0}
layoutDirection="rtl"
ref={ref}
scrollEnabled={false} >
Working code for me
<PagerView
initialPage={0}
ref={ref}
scrollEnabled={false} >
This solution worked for me.

Rendering user post JSON data in react native

Hello i'm currently working with React native using my rails api to retrieve user micropost data. The data renders in my log but comes up blank in react native. Honestly not sure what i'm doing wrong. can anyone help? Maybe the JSON is the problem?
Here is the JSON data:
[{"id":4,"content":"fool","user_id":1,"created_at":"2018-06-21T00:50:08.343Z","updated_at":"2018-06-21T00:50:08.343Z","picture":{"url":null}},{"id":3,"content":"pool\r\n","user_id":1,"created_at":"2018-06-21T00:50:04.644Z","updated_at":"2018-06-21T00:50:04.644Z","picture":{"url":null}},{"id":2,"content":"cool","user_id":1,"created_at":"2018-06-16T04:26:11.020Z","updated_at":"2018-06-16T04:26:11.020Z","picture":{"url":null}}]
And Here is my React Native code:
import React, { Component } from "react";
import { FlatList, StyleSheet, Text, View, AsyncStorage } from "react-
native";
const ACCESS_TOKEN = 'access_token';
export default class App extends Component {
state = {
data: []
};
componentWillMount() {
this.fetchData();
}
fetchData = async () => {
let accessToken = await AsyncStorage.getItem(ACCESS_TOKEN);
const response = await fetch("https://example.com/api/users/"+accessToken);
const json = await response.json();
this.setState({ data: json.data });
};
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
keyExtractor={item => item.toString()}
renderItem={({ item }) =>
<Text>
//also tried {`${item.content}`}, didn't work
{`${item.microposts.content}`}
</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
marginTop: 15,
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
}
});
Remove the extra }
Please optimize code by declaring renderItem as such
renderItem={({ item }) => <Text>{item.microposts && item.microposts.content}</Text>}

Can this onPress, called in TochableOpacity, return a Text component?

[
the image is the resultof when you console.log(this.state.fixtures)
I havent run into an error, but also havent gotten a result. Just trying to pass the individual match, from the .map(), to the Card component. Not sure if the onPress should be called in the TouchableOpacity. Been looking at this so a couple of day, any feedback s appreciated. Thank You.
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, LayoutAnimation } from 'react-native';
import { Card, CardSection } from '../common';
//import ListOf from './ListOf';
export default class LeagueCard extends Component {
state ={
fixtures: null
}
componentDidMount = () => {
const {league_name, league_id } = this.props.league
{this.getMatches(league_id)}
}
getMatches = (league_id) => {
let legaueID = league_id
let fixArray = []
//console.log(legaueID)
fetch(`https://apifootball.com/api/?action=get_events&from=2016-10-30&to=2016-11-01&league_id=${legaueID}&APIkey=42f53c25607596901bc6726d6d83c3ebf7376068ff89181d25a1bba477149480`)
.then(res => res.json())
.then(fixtures => {
fixtures.map(function(fix, id){
fixArray =[...fixArray, fix]
})
this.setState({
fixtures: fixArray
})
console.log(this.state.fixtures)
})
}
display = () => {
//console.log(this.state.fixtures)
if(this.state.fixtures != null){
this.state.fixtures.map(function(match, id){
//console.log(match)
return (
<Text>match</Text>
)
})
}
}
render(){
const {league_name, league_id } = this.props.league
return(
<View>
<TouchableOpacity
onPress={() => this.display()}
>
<Card>
<CardSection>
<Text>{league_name}</Text>
</CardSection>
</Card>
</TouchableOpacity>
</View>
)}
}
enter code here
import React, {Component} from 'react';
import {View, Text, TouchableOpacity, LayoutAnimation} from 'react-native';
import {Card, CardSection} from '../common';
export default class LeagueCard extends Component {
constructor(props) {
super(props);
this.state = {
fixtures: null,
matches: []
}
}
componentDidMount() {
const {league_name, league_id} = this.props.league;
this.getMatches(league_id)
};
getMatches = (league_id) => {
let legaueID = league_id;
let fixArray = [];
fetch(`https://apifootball.com/api/?action=get_events&from=2016-10-30&to=2016-11-01&league_id=${legaueID}&APIkey=42f53c25607596901bc6726d6d83c3ebf7376068ff89181d25a1bba477149480`)
.then(res => res.json())
.then(fixtures => {
fixtures.map(function (fix, id) {
fixArray = [...fixArray, fix]
});
this.setState({
fixtures: fixArray
})
})
};
display = () => {
if (this.state.fixtures != null) {
this.setState({
matches: this.state.fixtures.map(match => <Text>{match.country_name}</Text>)
});
}
};
render() {
const {league_name, league_id} = this.props.league;
return (
<View>
<TouchableOpacity onPress={this.display}>
<Card>
<CardSection>
{this.state.matches}
</CardSection>
</Card>
</TouchableOpacity>
</View>
)
}
}
I made the changes I think will render your matches for you. I made your display() f set the state.matches of your LeagueCard, which will now be an array of Text components each displaying match. The Array.prototype.map function in JavaScript returns a new array which should then be used.
Also should mention that I added a constructor where I initialize state, though that is not strictly necessary it is a good practice.
Watch out for typos too, you have one in getMatches which I did not fix.
Edit: I changed match to match.country_name as you can't give objects directly to a Text component. You will need to grab each key/value pair of the object you want to display.
this will not show any error to you, but your components will not render, because react will not know where to render it, a workaround to this problem is try something like this
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, LayoutAnimation } from 'react-native';
import { Card, CardSection } from '../common';
//import ListOf from './ListOf';
export default class LeagueCard extends Component {
state ={
fixtures: null,
showTextList: false
}
componentDidMount = () => {
const {league_name, league_id } = this.props.league
{this.getMatches(league_id)}
}
getMatches = (league_id) => {
let legaueID = league_id
let fixArray = []
//console.log(legaueID)
fetch(`https://apifootball.com/api/?action=get_events&from=2016-10-30&to=2016-11-01&league_id=${legaueID}&APIkey=42f53c25607596901bc6726d6d83c3ebf7376068ff89181d25a1bba477149480`)
.then(res => res.json())
.then(fixtures => {
fixtures.map(function(fix, id){
fixArray =[...fixArray, fix]
})
this.setState({
fixtures: fixArray
})
})
}
display = () => {
//console.log(this.state.fixtures)
this.setState({showTextList: true})
}
render(){
const {league_name, league_id } = this.props.league
return(
<View>
<TouchableOpacity
onPress={() => this.display()}
>
<Card>
<CardSection>
<Text>{league_name}</Text>
{this.state.showTextList && this.state.fixtures &&
this.state.fixtures.map((match, id) => (<Text>{match}</Text>))
}
</CardSection>
</Card>
</TouchableOpacity>
</View>
)}
}
I just put the text list inside your CardSection, because i belive you want to render the list inside it,but feel free to put this wherewver you want

Resources