React Native Navigation set image name with navigation.getParam() - javascript

My frist question on Stackoverflow :)
I'am using React Navigation. How can i load a image by the value of navigation.getParam('Country')?. This Image isn't loading (error code 500)
constructor(props) {
super(props);
this.state = { isLoading: true}
const { navigation } = this.props;
this.number = navigation.getParam('number');
this.country = navigation.getParam('country');
}
return (
<View style={bubble.container}>
<Text>{this.country}</Text>
<Image source={require('./img/flags/'+ this.country +'.png')} style={{width: 30, height: 30}}/>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <View style={bubble.wrapper}>
<Text selectable>{item.text}</Text>
<View style={bubble.footer}>
<View style={{flex: 1}}>
<Text style={bubble.sender}>{item.sender}</Text>
</View>
<View style={{flex: 1}}>
<Text style={bubble.time}><TimeAgo time={item.datetime} interval={20000}/></Text>
</View>
</View>
</View>}
/>
</View>
);

First of all, make sure your img is available in your path of the JS code,
assume your file of the js code is Country.js, so, the structure of your folder should be :
--Country.js (File)
--img (folder)
--flags (folder)
--country.png (an image)
and then, try to change your code look's like this:
render(){
const {country} = this.props.navigation.state.params
return (
<View style={bubble.container}>
<Text>{country}</Text>
<Image source={require('./img/flags/'+ country +'.png')} style={{width: 30, height: 30}}/>
<FlatList
..your setting
/>
</View>
)
}
Don't need to declare the params in constructor, you can declare the param of React Navigation in componentDidMount()/componentWillMount()/ even in render(){}

I have load my image by URL
<Image source={{uri: 'http://192.168.1.222/img/'+ countryvar + '.png'}} style={{width: 30, height: 30}}/>

Related

undefined is not a function (near '...this.state.results.map...')

I'm new at react native.I have a problem that i've been dealing for a few days.I want to show my data with map.Can you guys show me where i did wrong?
(I think i made mistake in the results inside scrollview)
class Movie extends Component{
state= {
apiurl:'http://www.omdbapi.com/.............................',
s:'',
results: [],
selected:{}
}
searchFunc(s) {
this.setState({s: s})
axios(this.state.apiurl+ "&s="+s).then(response =>
this.setState({results: response.data.Search[0]}));
console.log(this.state.results)
}
render() {
return(
<View style={{flex:1,backgroundColor:'#356292'}}>
<View
style={styles.sectionContainer}>
<View style={styles.section}>
<TextInput style={styles.section2}
onChangeText = {(s) => this.searchFunc({s})}
value={this.state.s}
placeholder="Movies,Series.."
>
</TextInput>
<TouchableOpacity
style={{justifyContent: 'center', alignItems: 'center'}}
onPress={() => this.searchFunc()}>
<Image
source ={require('../img/seach.png')}
style={{width:width*0.05,height:height*0.03}}
>
</Image>
</TouchableOpacity>
</View>
</View>
<ScrollView style={styles.scroll}>
{this.state.results.map(results=>(
<View key={this.state.results.imdbID}
style={styles.scroll2}>
<Image source={{uri: this.state.results}}
style={{width:width*0.3, height:height*0.4}}>
</Image>
<Text style={styles.heading}>
{this.state.results.Title}
</Text>
</View>
))}
</ScrollView>
</View>
);
}
From the comments from your original post, i'm guessing response.data.Search[0] is also an array. If so your results state update is okay. Otherwise you should set the results state to response.data.Search.
Other problem I noticed in your code is in the map function, you are mapping the array with each item refering to the result variable, but in your jsx, you are trying to access the results state variable. It should be
<ScrollView style={styles.scroll}>
{
this.state.results.map(result => (
<View
key={result.imdbID}
style={styles.scroll2}
>
<Image
source={{uri: result.image}} // use correct key from result object
style={{width:width*0.3, height:height*0.4}}
/>
<Text style={styles.heading}>{result.Title}</Text>
</View>
))
}
</ScrollView>
Also in your Textinput onChangeText callback function, you dont have to pass that value as an object. You can change it to
<TextInput
style={styles.section2}
onChangeText={(s) => this.searchFunc(s)}
value={this.state.s}
placeholder="Movies,Series.."
/>
I quess you are supposed to pass Search to the state and not the Search[0], which is the object and not map, the reason map function is not working on it.
axios(this.state.apiurl+ "&s="+s).then(response =>
this.setState({results: response.data.Search}));
console.log(this.state.results)
Coincidently, I have created an app using same movie API, you can find it here: Github Repo, Movie App

Get text from TextView and copy it to clipboard in react native

I want to copy value inside textview by clicking to icon. This is what I've done so far:
render() {
return (
<View style={{marginTop: 50, marginLeft: 50}}>
<View>
<Text>Логин:</Text>
<Text ref='myText'>45645546654</Text>
</View>
<TouchableOpacity onPress={() => Clipboard.setString(this.refs.myText.props.children)}>
<View>
<MaterialIcons
name='content-copy'
size={21}
/>
</View>
</TouchableOpacity>
</View>
);
}
Workspace: https://snack.expo.io/#jasurkurbanov/updated2
It is somewhat working on snack. But what when I am running it on my phone I am getting error.
Undefinied is not an object ('evaluating '_this.refs.myText.props.children')
You should defined your refs variable on constructor().
for example:
constructor() {
...
this.textViewRefs = React.createRef();
...
}
render() {
return (
...
<Text ref={this.textViewRefs}>45645546654</Text>
...
)
}
look this https://reactjs.org/docs/forwarding-refs.html for further information

I cannot figure out how to make ListView work properly

I am trying to render a list in React Native, however, nothing ever shows. I am logging the list before render as well and it is showing that the data field is being populated, but nothing is being shown.
This is the ListView code that I am trying that is NOT working.
This is the way that I am currently rendering the list. This method is working for me.
The reason that I want to use ListView instead of the current method that I am using is because I was reading from the documentation that ListView has better properties and performance.
Thank you!
Try destructuring correctly your item in renderItem. I mean:
<FlatList
data={this.state.users}
renderItem={({item}) => {
return (
<View>
<Image source={{uri: item.image}} style={{width: 150, height: 150}} />
<Text>{item.login}</Text>
</View>
)
}}
keyExtractor={(user) => user.id}
/>
Or, if you prefer to call it as info, define a function:
renderItem = (info) => {
return (
<View>
<Image source={{uri: info.image}} style={{width: 150, height: 150}} />
<Text>{info.login}</Text>
</View>
)
}
And call it like
<FlatList
data={this.state.users}
renderItem={({item}) => this.renderItem(item)}
keyExtractor={(user) => user.id}
/>
See more in the offical doc
You need to extract the item property from your data property in the FlatList
<FlatList
data={this.state.users}
renderItem={({item}) => {
return (
<View>
<Image source={{uri: item.image}} style={{width: 150, height: 150}} />
<Text>{item.login}</Text>
</View>
)
}}
keyExtractor={(user) => user.id}
/>
Note {item} in the renderItem callback
Another example
<FlatList
data={this.state.users}
renderItem={(data) => {
return (
<View>
<Image source={{uri: data.item.image}} style={{width: 150, height: 150}} />
<Text>{data.item.login}</Text>
</View>
)
}}
keyExtractor={(user) => user.id}
/>

React Native - Navigation from another file

So, I'm using 2 files: The components.js where I define all parts and molds I'll use in my app, and the App.js, which has the logic and major stuff.
To sum things up, I've defined a Card class in the components.js that has a button at the end. Here is the code for the Card:
export class Card extends Component {
render() {
return (
<View style={{height: 700}}>
<View style={{flex: 8, backgroundColor: 'white', borderRadius: 20}} >
<Image source={{uri: this.props.pic}} style={styles.img}/>
<Text style={{flex: 1, fontWeight: 'bold',fontSize: 30, paddingTop: 10}}> {this.props.nome}</Text>
<Text style={{flex: 1, fontSize: 20}}> {this.props.descricao}</Text>
<TouchableHighlight style={{flex: 1}} onPress={() => ???????} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>Mais informações</Text>
</View>
</TouchableHighlight>
</View>
</View>
);
}
}
And I use it in the App.js as follows:
import {Card} from "./components.js";
class App extends Component {
render() {
return (
<View style={{flex: 1, backgroundColor:"#e6e6e1"}}>
<ScrollView>
{this.state.locations.map((pico, key) =>
<Card key={key} pic={pico.img[0]} nome= {pico.nome_do_pico} descricao={pico.how}/>
)}
</ScrollView>
</View>
);
}
}
(I've omitted the parts where it gets the info from the server and puts into the locations array)
What I need is for the button to navigate to another screen, called "Details", and I have tried a few things on the onPress but nothing has worked so far. The documentation for reactnavigation uses this.state.navigation.navigate("Details") as example, but since the Card is in another file it can't access the this.state.navigation. Any ideas?
Try if you can solve the problem by modifying the following part of your code:
in app.js
<Card key={key} pic={pico.img[0]} nome= {pico.nome_do_pico} descricao={pico.how} navigation={navigation}/>
in components.js:
<TouchableHighlight style={{flex: 1}} onPress={() => navigation.navigate('Details', {YourParameters: xx } } underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>Mais informações</Text>
</View>
</TouchableHighlight>

Pass, Receive, and Use function into child Component

I'm still learning ReactJS / React Native and I'm stuck with a stupid thing I'm sure. Here's my case: I want to receive data in my child component and display it in a Modal. So:
I have a function like this (axios, API, ...):
getProductInfo = (product_id) => {
axios.get(
`API-EXAMPLE`
)
.then((response) => {
this.setState({
isVisible: false,
productInfo: response.data
})
console.log(this.state.productInfo);
})
}
I pass the function to my Child Component with the "onModalPress":
<CatalogList productsList={this.state.displayProducts} onModalPress={this.getProductInfo}/>
And here, some info about the Child Component:
const CatalogList = ({productsList, onModalPress}) => (
<Card containerStyle={styles.container}>
<View style={{ padding:20, margin:0, flexDirection: 'row', flexWrap: 'wrap', flex: 1, justifyContent: 'space-between' }}>
{
productsList.map((p, i) => {
return (
<TouchableHighlight key={i} onPress={() => onModalPress(p.id)}>
<View style={style.card}>
<View style={style.content}>
<View style={{width: 170, zIndex: 2}}>
<Text style={style.name}>{p.id}</Text>
<Text style={style.name}>{p.name}</Text>
<Text style={style.winemaker}>Domaine : {p.domain}</Text>
<Text style={style.winemaker}>Origine : {p.wine_origin}</Text>
<Text style={style.aop}>Appellation : {p.appellation}</Text>
</View>
<Image
style={style.image}
source={{ uri: p.image, width: 140, height: 225, }}
/>
</View>
<View style={style.entitled}>
<Text style={[style.priceText, style.cadetGrey]}>{p.publicPriceText}</Text>
<Text style={style.priceText}>{p.subscriberPriceText}</Text>
</View>
<View style={style.row}>
<Text style={[style.price, style.cadetGrey]}>{p.price} €</Text>
<Text style={style.price}>{p.subscriber_price} €</Text>
</View>
<View style={[{backgroundColor: p.label_colour}, style.label]}>
<Text style={style.labelText}>{p.label}</Text>
</View>
<Modal isVisible={false}>
<View style={{ flex: 1 }}>
{/* <Text>{productInfo.rewiew_wine_waiter}</Text> */}
</View>
</Modal>
</View>
</TouchableHighlight>
);
})
}
</View>
</Card>
);
The "p.id" comes from another data (productList) that I get with another Axios API Call. With "p.id" I get the product_id I need in my function
getProductInfo
Everything works and I display the info inside my console.log (this.state.productInfo).
My issue and I think is easy... It's how can I "store/stock" this info I have in the console.log in a const/props to use it in my Modal and call it like in this example:
<Modal isVisible={false}>
<View style={{ flex: 1 }}>
<Text>{productInfo.rewiew_wine_waiter}</Text>
</View>
</Modal>
Of course, any other advice is welcome!
React is all about one-way data flow down the component hierarchy
Let's assume that you have a Container component that fetch all the data:
class MyContainer extends Component{
state = {
myItensToDisplay: []
}
componentDidMount(){
//axios request
.then(res => this.setState({myItensToDisplay: res.itens}))
}
}
Looking good! Now you have all the data you want to display fetched and stored in your container's state. Let's pass it to a Itemcomponent:
class MyContainer extends Component{
// All the code from above
render(){
const itens = this.state.myDataToDisplay.map( item =>{
return(<Item name={item.name} price={item.price} />);
})
return(
<div>
{itens}
</div>
)
}
}
Now you are fetching all the data you want to display in a parent component and distributing that data to it's childrens via props.

Categories