How Can I Use a Component by Functions Response in React Native? - react-native

I'm trying to show a Lottie animation if the API response true. Here is my code:
export default class Register extends Component{
constructor(props){
super(props);
this.state = {
//variables
};
}
buttonClick = () =>{
//variables
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({variables})
};
fetch('api_url',requestOptions)
.then((response) => { return response.json() } )
.catch((error) => console.warn("fetch error:", error))
.then((response) => {
console.log(response)
if(response == "true"){
<LottieView
style={styles.success}
source = {require("./lottie/success.json")}
autoPlay = {true}
loop={false}
/>
}
})
}
render(){
return (
//textinputs and buttons
)
}
}
but the animation not showing up. I know it because of LottieView not in "render and return" parts but I don't know how can I fix it.

Add a useState isFetched, default value is false. If response is true, change state to true.
In render add this:
isFetched && (
<LottieView
style={styles.success}
source = {require("./lottie/success.json")}
autoPlay = {true}
loop={false}
/>
)

Related

How to store API response in state And pass this response value to another screen as params in react native

I am new to react native. I have created A screen. Where I am getting response from API. but now I want to store that response in state. and I want to send that value to another screen by navigation params.
my response is like this ->
Array [
Object {
"phpid": 10,
},
]
here is my code
constructor(props) {
super(props);
this.state={
};
}
fetch('https://xuz.tech/Android_API_CI/uploaddata/t_details?query=', {
method: 'POST',
headers: {'Accept': 'application/json, text/plain, */*', "Content-Type": "application/json" },
body: JSON.stringify([{"==some values=="}])
})
.then((returnValue) => returnValue.json())
.then(function(response) {
console.log(response)
return response.json();
render(){
return (
<View style={{flex: 1}}>
color="black" onPress={() => this.props.navigation.navigate("FormItems",{i want to send value to formitems})} />
</View>
)}
Set your state once you receive your response, then use your state as params when navigating. Once your fetch has been resolved:
this.setState({ response: response.json() });
Sending params to another screen is fairly simple, you just need to pass an object as the second parameter to navigate.
this.props.navigation.navigate('FormItems', {
form: this.state.response,
});
The receiving component will then need to read those params:
class DetailsScreen extends React.Component {
render() {
const { navigation } = this.props;
return (
<Text>{JSON.stringify(navigation.getParam('form', 'some default'))}</Text>
}
}
A full explanation on how to use params with react-navigation v4 can be found here: https://reactnavigation.org/docs/4.x/params
Use it like this. first initialise the state and when you get data from api set the data in state and when button press pass the data to new screen in params.
import React, { Component } from 'react';
import { Text, View } from 'react-native';
export default class Example extends Component {
state = {
data: [], // initialize empty state
};
componentWillMount() {
this.requestData();
}
requestData = () =>{
fetch('https://xuz.tech/Android_API_CI/uploaddata/t_details?query=', {
method: 'POST',
headers: {'Accept': 'application/json, text/plain, */*', "Content-Type": "application/json" },
body: JSON.stringify([{"==some values=="}])
})
.then((returnValue) => returnValue.json())
.then(function(response) {
this.setState({
data:response //set data in state here
})
})
}
render() {
return (
<View style={{ flex: 1 }}>
<Button
color="black"
onPress={() =>
this.props.navigation.navigate('FormItems', {
data: this.state.data, // pass data to second screen
})
}
/>
</View>
);
}
}

navigation.getParam is not a function. (In 'navigation.getParam('message', 'hiiii')', 'navigation.getParam' is undefined) in react native

I am new to react native. I want to send API data from one screen to another screen And want to display that data on that screen. but I am getting error like = navigation.getParam is not a function. (In 'navigation.getParam('message', 'hiiii')', 'navigation.getParam' is undefined). please help , thanks.
here is my first screen code from where I send data
class Browse extends Component {
constructor(props) {
super(props);
this.state = {
ListView:[]
};
}
state = {
categories: [],
error: [],
};
ListView () {
const {navigation} = this.props
AsyncStorage.multiGet(["application_id", "created_by"]).then(response => {
console.log(response[0][1]) // Value1
console.log(response[1][1]) // Value2
fetch("https://xys.tech/Android_API_CI/get_lead_data_for_user", {
method: "POST",
headers: { 'Accept': 'application/json, text/plain, */*', "Content-Type": "application/json" },
body: JSON.stringify([{ id:response[1][1], application_id:response[0][1]}]),
})
.then((returnValue) => returnValue.json())
.then((response) => {
alert(JSON.stringify(response))
this.props.navigation.navigate("ListView", {
message: "hiiiii",
});
})
here is my second screen code where I want to show API data
const { width } = Dimensions.get("window");
class Browse extends Component {
constructor(props) {
super(props);
this.state ={
Email:"",
}
render() {
const { profile, navigation } = this.props;
const tabs = [""];
const ListView = navigation.getParam('message','hiiii')
//const route = this.props
return (
<View style={{flex: 1}}>
<ScrollView>{ListView}</ScrollView>
</View>
);
}
}
Try with route like this
this.props.route.params.message

Invariant Violation in React Native: Text strings must be rendered within a <Text> component

I'm working on a React-Native project with REST APis, and I've currently got an invariant violation error. I've experienced this before, but I can't quite figure out what is causing it and how to fix it. If someone could point me in the right direction, I would really appreciate it! The full error is pictured below, and appears to be referencing a number of tags in the code, so I'm unsure exactly where it is originating. Thank you for reading, and thanks in advance!
The code is here:
import React, { Component } from 'react'
import { View, Text, Image, StyleSheet, FlatList} from 'react-native';
import * as Font from 'expo-font';
import styled from 'styled-components';
import dimensions from '../components/ScreenSize';
import colours from '../components/Colours';
import { Audio } from 'expo-av';
import { TouchableHighlight } from 'react-native-gesture-handler';
const client_id = {Client_ID}
const client_secret = {Client_Secret}
const item = ({item}) => (
<View style={{ flex:1, flexDirection: 'column', margin:1}}>
<TouchableHighlight onPress={() => this.fetchTracks(item.id)}>
<View>
<Text>{item.name}</Text>/>
</View>
</TouchableHighlight>
</View>
)
export default class HomeScreen extends React.Component {
state={
fontsLoaded:false,
}
async componentDidMount() {
await Font.loadAsync({
'montserrat-regular': require('../assets/fonts/Montserrat/Montserrat-Regular.ttf'),
'montserrat-light': require('../assets/fonts/Montserrat/Montserrat-Light.ttf'),
'montserrat-semibold': require('../assets/fonts/Montserrat/Montserrat-SemiBold.ttf'),
'montserrat-bold': require('../assets/fonts/Montserrat/Montserrat-Bold.ttf'),
}
).then(() => this.setState({ fontsLoaded:true }))
this.getToken();
this.setAudio();
}
constructor (props) {
super(props)
this.playbackInstance=null;
this.state = {
playing:false,
token: '',
DATA:[],
};
}
setAudio=() => {
Audio.setAudioModeAsync({
allowsRecordingIOS:false,
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
playsInSilentModeIOS: true,
shouldDuckAndroid: true,
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
playThroughEarpieceAndroid: false,
});
}
componentDidCatch(error, info)
{
console.log(error, info.componentStack);
}
getToken = async() =>
{
try
{
const getspotifytoken = await fetch("https://accounts.spotify.com/api/token",
{
method:'POST',
body: `grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
const spotifytoken = await getspotifytoken.json();
this.setState({
token: spotifytoken.access_token
});
console.log(this.state.token);
}
catch(err)
{
console.log("Error fetching data", err);
}
}
search = async () => {
try
{
console.log("Searching: mood")
const spotifyApiCall = await fetch(`https://api.spotify.com/v1/browse/categories/mood/playlists?`, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${this.state.token}`,
"Content-Type":'application/json'
}
})
const spotify = await spotifyApiCall.json();
console.log("Items", spotify);
this.setState({
DATA: spotify.playlists.items,
})
}
catch (err)
{
console.log("Error fetching data", err);
}
}
fetchTracks = async (playlistId) => {
console.log('Playlist ', playlistId)
try
{
const getplaylist = await fetch(`https://api.spotify.com/v1.playlist/${playlistId}`,
{
method:'GET',
headers: {
Accept:"application/json",
Authorization:`Bearer ${this.state.token}`,
"Content-Type":"application/json"
}
});
const playlist = await getplaylist.json();
console.log('music ', playlist.tracks.items[0].preview_url);
}
catch (err)
{
console.log("Error fetching data ", err);
}
}
async _loadNewPlaybackInstance(playing, track) {
if(this.playbackInstance != null)
{
await this.playbackInstance.unloadAsync();
this.playbackInstance.setOnPlaybackStatusUpdate(null);
this.playbackInstance = null;
}
const source = {uri: track};
const initialStatus = {
shouldPlay: true,
rate: 1.0,
shouldCorrectPitch: true,
volume: 1.0,
isMuted: false
};
const {sound, status} = await Audio.Sound.createAsync(
source.initialStatus);
this.playbackInstance=sound;
this.playbackInstance.setIsLoopingAsync(false);
this.playbackInstance.playAsync();
if (this.state.selected === playlistId) {
console.log("Playing, so stop");
this.setState({selected:null});
this.playbackInstance.pauseAsync();
return;
}
this.setState({ selected:playlistId});
this._loadNewPlaybackInstance(true, playlist.tracks.items[0].preview_url);
}
render() {
if(!this.state.fontsLoaded ) {
return null
}
return (
<Container>
<Titlebar>
<Title>Music</Title>
</Titlebar>
<HeaderBar2>
<TouchableHighlight onPress={() => this.search()}>
<Header2>Playlists for your Mood</Header2>
</TouchableHighlight>
</HeaderBar2>
<View style={styles.MainContainer}>
{
this.state.DATA.length == 0 &&
<Text style={{padding:10, color:'#D3D3D3'}}/>
}
<FlatList
data = {this.state.DATA}
renderItem={item}
keyExtractor = {item.id}
numColumns={2}
extraData = {this.state}
/>
</View>
</Container>
);
}
}
I think u just have a little typo ..
check this line: <Text>{item.name}</Text>/>
change the last Text to </Text>

Displaying multiple data in react native

I am pretty new to react native. I am currently grabbing data from my node.js and trying to show all the data I grabbed into my View. In react.js, i did
documnet.getElementById.append().
What is the best way to do it in react native?
my code looks something like this
class GlobalRankings extends Component{
constructor(){
super();
this.state = {
}
this.getGlobalRankings();
}
getGlobalRankings(){
var request = new Request(checkEnvPort(process.env.NODE_ENV) + '/api/global_rankings', {
method: 'GET',
headers: new Headers({ 'Content-Type' : 'application/json', 'Accept': 'application/json' })
});
fetch(request).then((response) => {
response.json().then((data) => {
console.log(data);
for (var i in data.value){
console.log(data.value[i]); //where i grab my data
}
});
}).catch(function(err){
console.log(err);
})
}
render(){
return(
<View style={styles.container}>
// want my data to be here
</View>
)
}
}
Thanks for all the help
You can make an array in state in constructor, this.state = { arr: [] }
Then you assign the data array you get from the response.
fetch(request).then((response) => {
response.json().then((data) => {
this.setState({ arr: data.array });
});
}).catch(function(err){
console.log(err);
});
Then in the component body,
<View style={styles.container}>
{
this.state.arr.map((value, index) => {
return(
<Text key={index}>{value.text}</Text>
);
})
}
</View>

Infinite FlatList problem - React Native , Expo

I am using Expo for developing react-native applications.
I want to make an Infinite list, but every time onEndReached event is fired, FlatList is refreshed automatically scrolls to the top of the page!
import React, { useState, useEffect } from "react";
import { SafeAreaView, Text, FlatList } from "react-native";
export default function App() {
const [config, setConfig] = useState({
result: [],
page: 0
});
async function fetchData() {
const response = await fetch("http://192.168.2.49:3500/q", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({ page: config.page })
});
const data = await response.json();
setConfig({
result: [...config.result, ...data],
page: config.page++
});
}
const onEndReached = async () => {
await setConfig({
page: config.page++
});
fetchData();
};
useEffect(() => {
fetchData();
}, []);
return (
<SafeAreaView>
<Text>Current Page : {config.page}</Text>
<FlatList
data={config.result}
renderItem={o => <Text>X :{o.item.t.c}</Text>}
keyExtractor={item => item._id}
onEndReached={() => onEndReached()}
onEndReachedThreshold={0}
></FlatList>
</SafeAreaView>
);
}
You are calling setConfig twice, before calling fetchData and after a successful API request. Which triggers a rerender.
I refactored your code, try this.
import React, { useState, useEffect, useCallback } from 'react';
import {
SafeAreaView,
Text,
FlatList,
NativeSyntheticEvent,
NativeScrollEvent,
} from 'react-native';
export default function App() {
const [config, setConfig] = useState({
result: [],
page: 0,
});
const [isScrolled, setIsScrolled] = useState(false);
const fetchData = useCallback(() => {
async function runFetch() {
const response = await fetch('http://192.168.2.49:3500/q', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ page: config.page }),
});
const data = await response.json();
setConfig({
result: [...config.result, ...data],
page: config.page++,
});
}
runFetch();
}, [config.page, config.result]);
const onEndReached = useCallback(() => fetchData(), [fetchData]);
const onScroll = useCallback(
e => setIsScrolled(e.nativeEvent.contentOffset.y > 0),
[],
);
useEffect(() => {
fetchData();
}, [fetchData]);
return (
<SafeAreaView>
<Text>Current Page : {config.page}</Text>
<FlatList
data={config.result}
keyExtractor={item => item._id}
onEndReached={onEndReached}
onEndReachedThreshold={0.1}
onScroll={onScroll}
renderItem={o => <Text>X :{o.item.t.c}</Text>}
/>
</SafeAreaView>
);
}