Passing Barcode Scanned Data to Second Screen - react-native

I'm trying to pass the data I have received from scanning a barcode. I'm able to print the data using JSON.stringify(data) and the data is being passed but I just can't seem to display it.
Passing the data successfully with:
_handleBarCodeRead = data => {
Alert.alert(
'Scan successful!',
JSON.stringify(data)
);
const { navigate } = this.props.navigation;
navigate('KnownProduct', {data})
};
Attempting to render the data on this page:
render(){
const { navigate } = this.props.navigation;
return(
<View style={styles.container}>
<Text>{this.props.navigation.state.params.data.toString}</Text>
</View>
);
I know the navigation works correctly because if I hard-code the value the screen does navigate after scanning a barcode and display the hard-coded value. However, I think I'm trying to call the data incorrectly with: this.props.navigation.state.params.data.toString but having no luck figuring out how to display the passed data.
Any react native experts able to help a newbie?
OK.... So I figured it out... thanks to one commenter who pointed out I should pass the data like so:
navigate('KnownProduct', {data: data})
And then what was missing in the redirection page was:
<Text>{this.props.navigation.state.params.data.data}</Text>
data.data got me!

Try this :
navigate('KnownProduct', {data:JSON.stringify(data)})
AND
<Text>{this.props.navigation.state.params.data}</Text>

try this
navigate('KnownProduct', {data:data.data})
<Text>{this.props.navigation.getParam('data')}</Text>

Related

How to output fetch request response in react native

I want to print out the response of my fetch request in react native.
How would I do this to get the response inside a Text?
function Nft() {
fetch(
"https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"
);
return (
<View>
<Text style={style.header}>Bitcoin Price</Text>
</View>
);
}
export default Nft;
Define state variable like following
const[price,setPrice]=useState(0);
then replace fetch code by following
fetch('https://api.coingecko.com/api/v3/simple/price? ids=bitcoin&vs_currencies=usd')
.then((res)=>res.json())
.then((response)=>{
//your response is like this ,{"bitcoin":{"usd":18993.39}}
let price= response?.bitcoin?.usd;
setPrice(price)
})
.catch((error)=>{
//here you can manage errors
})
In your component you can right in this way
<Text>{price}<Text>
Please refer the following code
fetch('https://api.coingecko.com/api/v3/simple/price? ids=bitcoin&vs_currencies=usd')
.then((res)=>res.json())
.then((response)=>{
//here you can get your output of fetch in the response variable
//whatever data you want to show here save in state variable and
//use that state variable to display.
})
.catch((error)=>{
//here you can manage errors
})
**In your component you can right in this way
<Text>{your state variable}<Text>

Why is data from useQuery undefined when I start screen?

When I start screen, I get data from useQuery
And by using useEffect, I get data and immediately sort this data.
After sorting data, I put this data to useState named flatlistdata.
And I draw screen by using Flatlist with this data.
Flatlist data should be sorted.
So I need to refined data before.
const { data: allFeedData, refetch: allFeedRefetch } = useQuery(SEE_ALL_FEED_ORDER);
const [flatlistdata, setFlatlistdata] = useState([]);
useEffect(() => {
allFeedRefetch();
setFlatlistdata(
[...allFeedData.seeAllFeedOrder].sort(function (a, b) {
return b.directFeedNumber - a.directFeedNumber;
})
);
}, []);
<FlatList
data={flatlistdata}
keyExtractor={(item) => item.id}
renderItem={RankRow}
refreshing={refreshing}
onRefresh={refresh}
/>
However when I click screen, it says undefined is not an object which means data is empty.
I think the problem here is that screen is drawn, before sorting data and putting it to useState...?
I need a little hint 😭
Please help me.
The query is an asynchronous operation, so, the data variable will always start out as undefined while the network request completes. There are two possible solutions.
In your useEffect, only set your state if data is defined. Wrap your setFlatlistData with if (allFeedData?.length) { ... }
Use the React Query selection prop to have Query do the same operation before allFeedData gets populated. Check the select prop in the docs for useQuery: https://react-query-v2.tanstack.com/reference/useQuery

Passing params in React Navigation 5

I'm trying to pass a few params between a Tab Navigator. Below is the structure of my program. In bold are the routes
App(Tab Navigator): { Main(stack) & Filter(screen) }
Main(Stack Navigator): { Home(screen) & MediaDetails(screen) }
I have a button on the screen associated with Filter which has an onPress() function. I'm passing a few params(but let's only consider the param to for the sake of this question).
this.props.navigation.navigate('Home', {
to: this.state.to,
}
Now in the screen associated with Home, I'm reading the param inside the state like this:
state = {
to: this.props.route.params.to
}
Inside App.js, I've set the initial value of to to be '2020' like this:
<Stack.Screen
name="Home"
component={HomeScreen}
initialParams={{
to: '2020'
}}
/>
The initial value is indeed set to 2020. I press the button. Let's say I'm setting to to 1900. Just before this.props.navigation.navigate executes, I console.log(this.state.to) the value and it is indeed updated to 1900. However, as the screen changes to Home, the value reverts back to 2020(observed via console.log)
Could someone point out the cause for this spooky behavior? I've been trying to debug this for many hours with no luck. React Navigation 5 is pretty new as well so couldn't find anything similar online. Any help will be greatly appreciated. Thank you for reading all the way.
Edit: Issue has been resolved and full code has been removed!
/* 1. Navigate to the Details route with params */
onPress={() => {
navigation.navigate('Details', {
itemId: 86,
otherParam: 'anything you want here',
});
}}
/* 2. Get the param */
const DetailsScreen = ({ route, navigation }) => {
const { itemId } = route.params;
const { otherParam } = route.params;
return (
<View></View>
);
};
for more info: https://reactnavigation.org/docs/params/
I solved this problem by updating the state in shouldComponentUpdate().
This bug was due to the state not being updated as the screen remained mounted.
This was possible because of ravirajn22 on GitHub who explained to me the reasoning behind this bug and a possible solution.
Link to the answer: https://github.com/react-navigation/react-navigation/issues/6863
As it is stated Here, you can do it like this:
navigation.navigate('otherStackName', {
screen: 'destinationScreenName',
params: { user: 'jane' },
});
In Functional Component write simple logic like this:-
In the parent component
<TouchableOpacity onPress={()=>navigation.navigate('childRoute', {data_Pass_to_Child: "Hello I am going to child component"})}>
In the child component
const Chat = ({route}) => {
console.log(route.params.data_Pass_to_Child);
return(whatever based on your UI)
}
Note:
Replace childRoute with your route name and also replace data {data_Pass_to_Child: "Hello I am going to child component"} with whatever data you want to pass.
send
props.navigation.navigate('YourScreenName', {
your_key: any_value
});
receive in YourScreenName.js
var valueReceived = props.navigation.state.params.your_key;

How to populate a FlatList's header with data from the network?

I have a FlatList that displays a user's comments and I want to also populate the header with the user's profile (which is a different network call from the one fetching the comments).
Here's how render() looks like:
render() {
return (
<FlatList
data = {this.state.comments}
renderItem = {this.renderComment}
ListHeaderComponent={this.renderHeader}
keyExtractor={(comment, index) => comment.id}
/>
)
}
and then renderHeader looks like:
renderHeader() {
return (
<ProfileView user={this.state.profile} />
)
}
I use fetch in componentWillMount and then setState in order to get the data (this part works fine).
Now the error I get on the simulator is
undefined is not an object (evaluating 'this.state.profile')
but when I remove the renderHeader method, comments are fetched properly.
Since I'm very new to RN, can you help me understand what is wrong and how to fix it?
This looks like simply an issue with accessing context. When you run the renderHeader method called by the FlatList it doesn't know what this relates to.
So, you can simply set this.renderHeader = this.renderHeader.bind(this) in your constructor() method.
Alternatively, you should also be able to use an arrow function to call it, as this automatically refers to the correct this context.
ListHeaderComponent={() => this.renderHeader()}

Importing Text from local json file in React native

I am wondering how the common way is to import a huge text to a View. In my case i am developing a React Native App for Android and iOS, and on one of my Views i want to present the "Terms of Use" document. Now when i just import/copy paste it into a Text Component it just can´t be the right solution, especially when i need to use localization to present the needed language. How would i "import" this Text-Block so it is nice formatted and i don´t need to put everything into my View:
<View style={styles.container}>
<Text style={styles.text}> |JSON - Text-file, with about 600 words -> Terms of Use document |</Text>
</View>
You can use:
import file from './config/TermsAndCondition.json';
then you can treat it as a javascript object:
file.description
I'd to it as JSON, especially if you need to bring some other (meta)data with the text. Where fetch(url) is called on componentWillMount and <Text>{this.state.hugeText}</Text> component is populated:
As a concept:
constructor(props) {
super(props);
this.state = {
hugeText: ''
};
}
componentWillMount() {
fetch('myText.json')
.then((res) => res.json())
.then((data) => {
this.setState({
hugeText: data.something
});
});
}
I tried fetch but it didn't work (wasn't able to find the file).
I tried this instead, and it worked:
// at top of file
var jsonData = require('./myfile.json');
// inside component definition
render() {
let deepProp = jsonData.whatever;
}