How to save/download generate QRCode inn react native - javascript

By using this code I am able to generate QRCode but , I don't know how to save that qrcode in png/jpeg format ono long press or automatic .
I need some help or idea to solve that .. I tried few examples but not getting success . I am keep trying.
import React, { Component } from 'react';
//import react in our code.
import { StyleSheet, View, TextInput, TouchableOpacity, Text,} from 'react-native';
// import all basic components
import QRCode from 'react-native-qrcode-svg';
//import QRCode
class App extends Component {
svg;
constructor() {
super();
this.state = {
inputValue: '',
inputValue2: '',
// Default Value of the TextInput
valueForQRCode: '',
// Default value for the QR Code
};
}
getTextInputValue = () => {
// Function to get the value from input
// and Setting the value to the QRCode
this.setState({ valueForQRCode: this.state.inputValue + this.state.inputValue2 });
};
shareQR =() =>{
this.svg.toDataURL((data) => {
const shareImageBase64 = {
title: "QR",
message: "Ehi, this is my QR code",
url: `data:image/png;base64,${data}`
};
Share.open(shareImageBase64);
});
}
render() {
return (
<View style={styles.MainContainer}>
<QRCode
value={"Abhigyan" + this.state.valueForQRCode}
//Setting the value of QRCode
size={250}
//Size of QRCode
bgColor="#000"
//Backgroun Color of QRCode
fgColor="#fff"
//Front Color of QRCode
getRef={(ref) => (this.svg = ref)}
onPress={() =>{shareQR()}}
/>
<TextInput
// Input to get the value to set on QRCode
style={styles.TextInputStyle}
onChangeText={text => this.setState({ inputValue: text })}
underlineColorAndroid="transparent"
placeholder="Enter text to Generate QR Code"
/>
<TextInput
// Input to get the value to set on QRCode
style={styles.TextInputStyle}
onChangeText={text => this.setState({ inputValue2: text })}
underlineColorAndroid="transparent"
placeholder="Enter text to Generate QR Code"
/>
<TouchableOpacity
onPress={this.getTextInputValue}
activeOpacity={0.7}
style={styles.button}>
<Text style={styles.TextStyle}> Generate QR Code </Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button}onPress={this.shareQR}>
<Text style={styles.buttonText}>Share</Text>
</TouchableOpacity>
</View>
);
}
}
export default App;
const styles = StyleSheet.create({
MainContainer: {
flex: 1,
margin: 10,
alignItems: 'center',
paddingTop: 40,
},
TextInputStyle: {
width: '100%',
height: 40,
marginTop: 20,
borderWidth: 1,
textAlign: 'center',
},
button: {
width: '100%',
paddingTop: 8,
marginTop: 10,
paddingBottom: 8,
backgroundColor: '#F44336',
marginBottom: 20,
},
TextStyle: {
color: '#fff',
textAlign: 'center',
fontSize: 18,
},
});
//Thanks .
// In QRCode I am able to generate and QRCode scanner both I have done ,but how to download /save or share that qrcode ,Please help

This answer refers to react-native-qrcode-svg library, as written in the question comments.
With this library you can create an svg to show the QR you want and then access it by reference. So, create a reference in your component:
class App extends Component {
svg;
constructor() {
...
};
}
...
}
Assign it the QRCode, for example:
<QRCode
value={"Abhigyan" +this.state.valueForQRCode}
size={250}
color="#fff"
getRef={(ref?) => (this.svg = ref)}
/>
Now you can access its content with this.svg.toDataURL(//callback).
Example: you wanna share the QR as an image/png using react-native-share by clicking on a button which calls this function:
shareQR() {
this.svg.toDataURL((data) => {
const shareImageBase64 = {
title: "QR",
message: "Ehi, this is my QR code",
url: `data:image/png;base64,${data}`
};
Share.open(shareImageBase64);
});
}
This is just an example, if you prefer to use react-native-fs you can refer to the example given in the official repository.
Update to support onPress function
You're trying to pass onPress prop to QRCode, but QRCode does not support it. Instead, wrap it in a TouchableOpacity:
<TouchableOpacity onPress={this.shareQR}>
<QRCode
value={"Abhigyan" +this.state.valueForQRCode}
size={250}
color="#fff"
getRef={(ref?) => (this.svg = ref)}
/>
</TouchableOpacity>

You can use react-native-view-shot to create an image of QR code then you can save it in camera roll or disk storage.

Related

How to properly handle login from a React Native (Expo) Project Using JWT Token?

As part of my self-learning react-native project using expo I am using a Login component for which the code is reproduced below. The code works fine when the app is run in a web-browser. The JWT token is fetched and stored properly in the local storage and works fine even to fetch user credentials on the next screen(Authuser).
However, when published to expo and run on an android device, the login fails.
Could someone kindly have a look at the code to see where the fault lies. If you think I am jumping ahead of the learning curve, please point to a learning resource! Thanks in anticipation.
import * as React from 'react';
import { Text, View, StyleSheet, TextInput, Button, Alert } from 'react-native';
import { useForm, Controller } from 'react-hook-form';
import axios from 'axios';
export default function Login({navigation}){
const { register, setValue, handleSubmit, control, reset, formState: { errors } } = useForm({
defaultValues: {
email: '',
password: '',
}
});
const onSubmit = async (data) => {
await axios.post('https://example.com/apiLogin.php', data)
.then(function (response) {
if(response) {
if(response.data.success) {
localStorage.setItem('loginToken', response.data.token);
alert(response.data.message);
navigation.navigate("Authuser");
}else{
alert(response.data.message);
}
reset({
email: '',
password: ''
})
}
})
}
const onChange = arg => {
return {
value: arg.nativeEvent.text,
};
};
return (
<View style={styles.container}>
<Text style={styles.label}>Email</Text>
<Controller
control={control}
render={({field: { onChange, onBlur, value }}) => (
<TextInput
style={styles.input}
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
/>
)}
name="email"
rules={{ required: true }}
/>
<Text style={styles.label}>Password</Text>
<Controller
control={control}
render={({field: { onChange, onBlur, value }}) => (
<TextInput
style={styles.input}
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
/>
)}
name="password"
rules={{ required: true }}
/>
<View style={styles.horizonBtnsCtnr}>
<View style={styles.buttonContainer}>
<Button
color="#5CB85C"
title="Login"
onPress={handleSubmit(onSubmit)}
/>
</View>
<View style={styles.buttonContainer}>
<Button
color="#FF9912"
title="Register Here"
onPress={() => navigation.navigate("Register")}
/>
</View>
</View>
<View style={styles.buttonContainer}>
<Text style={{color: '#5CB85C', textAlign: 'center'}}
onPress={() => navigation.navigate("RequestOTP")}>
Forgot Password? Reset Here!
</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: 20,
padding: 8,
backgroundColor: '#4E5D6CFF',
},
label: {
color: '#FFFFFF',
margin: 10,
marginLeft: 0,
},
buttonContainer: {
padding: 10,
},
input: {
backgroundColor: '#FFFFFF',
borderColor: '#F0FFF0',
height: 40,
padding: 10,
borderRadius: 4,
},
horizonBtnsCtnr: {
flexDirection: 'row',
marginTop: 10,
justifyContent: "center",
alignItems: "center",
textAlign: "center",
}
});
With some more research after posting the question I was able to find a workable solution to the issue. I was wrong assuming that localStorage would work for mobile platform as well. I should have used AsyncStorage to set and get JWT token.
This is how I solved the problem:
I installed AsyncStorage in my expo project using
import AsyncStorage from '#react-native-async-storage/async-storage'.
I used AsyncStorage.setItem('loginToken', response.data.token) instead of localStorage.setItem('loginToken', response.data.token).
I used const loginToken = await AsyncStorage.getItem('loginToken') instead of const loginToken = await localStorage.getItem('loginToken').
That did the rest. Now I am being able to login from web as well as android simulator and my android phone and being successfully able to fetch the user credentials in authenticated page(s).

Cannot display Array in Flatlist format

Long story short, I'm trying to create a list of video-games. I have an autocomplete library that matches a game title with what I write in my input box.
I added a button that onPress triggers a function that pushes what I have in 'query'( which is what I am writing in my input box) into an array called myGamesArray
Then I'm trying to display myGamesArray in list form using Flatlist. But for some reason it is not showing up.
My code is a little messy because the solution I found to place a button next to my input box was by changing the flex direction to 'row'
I added a button right below the FlatList just to check if it would display underneath the inputbox (which it does) but for some reason the flatlist does not
Here's all my App.js
/*This is an example of AutoComplete Input/ AutoSuggestion Input*/
import React, { Component } from 'react';
//import react in our code.
import { StyleSheet, Text, TouchableOpacity, View, Image, Alert, FlatList } from 'react-native';
//import all the components we are going to use.
import Autocomplete from 'react-native-autocomplete-input';
import { Button, List, Container, ListItem, Header } from 'native-base';
//import Autocomplete component
//Demo base API to get the data for the Autocomplete suggestion
class App extends Component {
constructor(props) {
super(props);
//Initialization of state
//games will contain the array of suggestion
//query will have the input from the autocomplete input
this.state = {
myGamesArray: [],
games: [],
query: '',
};
}
componentDidMount() {
//First method to be called after components mount
//fetch the data from the server for the suggestion
fetch('https://api.rawg.io/api/games?page=1&platforms=18', {
"method": "GET",
"headers": {
"x-rapidapi-host": "rawg-video-games-database.p.rapidapi.com",
"x-rapidapi-key": "495a18eab9msh50938d62f12fc40p1a3b83jsnac8ffeb4469f"
}
})
.then(res => res.json())
.then(json => {
const { results: games } = json;
this.setState({ games });
//setting the data in the games state
});
}
findGame(query) {
//method called everytime when we change the value of the input
if (query === '') {
//if the query is null then return blank
return [];
}
const { games } = this.state;
//making a case insensitive regular expression to get similar value from the game json
const regex = new RegExp(`${query.trim()}`, 'i');
//return the filtered game array according the query from the input
return games.filter(game => game.name.search(regex) >= 0);
}
AddItemsToArray=()=>{
//Adding Items To Array.
this.state.myGamesArray.push( this.state.query.toString() )
// Showing the complete Array on Screen Using Alert (just to check if it's infact inside the array)
Alert.alert(this.state.myGamesArray.toString());
}
render() {
const { query } = this.state;
const games = this.findGame(query);
const comp = (a, b) => a.toLowerCase().trim() === b.toLowerCase().trim();
return (
<View>
<View style={styles.container}>
<Autocomplete
style={styles.autocompleteContainer1}
autoCapitalize="none"
autoCorrect={false}
//data to show in suggestion
data={games.length === 1 && comp(query, games[0].name) ? [] : games}
//default value if you want to set something in input
defaultValue={query}
/*onchange of the text changing the state of the query which will trigger
the findGame method to show the suggestions*/
onChangeText={text => this.setState({ query: text })}
placeholder="Selecione os jogos que voce quer receber!"
renderItem={({ item }) => (
//you can change the view you want to show in suggestion from here
//I GET ERROR WHEN TRYING TO ERASE (PS4) IN TEXT BOX ***NEED TO CHECK THIS
<View style={styles.iconContainer} >
<TouchableOpacity onPress={() => this.setState({ query: item.name})}
style={styles.itemContainer} >
<View>
<Image
style={styles.profilepic}
source={{uri: item.background_image}}
/>
</View>
<Text style={styles.itemText}>
{item.name} (PS4)
</Text>
</TouchableOpacity>
</View>
)}
/>
<Button
style={styles.addButton}
icon='plus'
title="Click Here To Add Value To Array"
onPress={() => this.AddItemsToArray()}
/>
<View style={styles.descriptionContainer}>
{games.length > 0 ? (
//Text inside input box
<Text style={styles.infoText}>{this.state.query}</Text>
) : (
<Text style={styles.infoText}>{this.state.query}</Text>
)
}
</View>
</View>
<View style={styles.container2}>
<Button
full></Button>
<FlatList
data={this.state.myGamesArray}
renderItem={({ item }) => (
<ListItem>{item}</ListItem>
)}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#fff',
flex: 1,
flexDirection:'row',
padding: 16,
marginTop: 40,
justifyContent: 'center',
},
container2: {
backgroundColor: '#fff',
flex: 1,
marginTop: 100,
alignItems: 'center',
justifyContent: 'center',
},
autocompleteContainer1: {
borderWidth: 1,
backgroundColor: "#fff",
borderColor: '#7843FF',
height: 50,
width:300
},
itemContainer: {
flex:1,
flexDirection: 'row',
borderWidth:0.5,
borderColor: '#7843FF',
paddingVertical: 5,
alignItems: 'center',
paddingRight: 60
},
addButton: {
width:50,
height: 50,
borderColor: '#7843FF',
borderWidth: 0.5,
backgroundColor: '#fff'
},
descriptionContainer: {
flex: 1,
justifyContent: 'center',
borderRadius: 10,
color: '#fff',
borderColor: '#7843FF'
},
itemText: {
fontSize: 15,
marginLeft: 10,
marginRight:30,
marginVertical:10,
color: '#000',
textAlign: 'left',
justifyContent: 'center'
},
infoText: {
textAlign: 'center',
color: '#000',
},
profilepic: {
flex: 3,
height: 60,
width: 60,
marginLeft:10,
borderRadius: 100,
},
});
export default App;
Issue
this.state.myGamesArray.push(this.state.query.toString()) is a state mutation. You need to actually do a state update and return a new array object reference.
Solution
Use a functional state update to access the previous state object, and shallow copy the old array into a new array reference and append the new query value to the end.
Also, logging or otherwise trying to reference the updated state right after enqueueing the update won't work like that, state is const and updated between render cycles so it'll enclose the current state.
AddItemsToArray = () => {
//Adding Items To Array.
this.setState(prevState => {
const { myGamesArray, query } = prevState;
return {
myGamesArray: [...myGamesArray, query.toString()],
};
},
// Use setState callback to alert with the updated state
() => {
// Showing the complete Array on Screen Using Alert (just to check if it's in fact inside the array)
Alert.alert(this.state.myGamesArray.toString());
},
);
}

How to save/download generate QR Code in react native using hooks?

I'm trying to build an app generator and scanner QR code in react native using hooks. I want a solution to save/download the QR code in the device after generating them. I need help plz, thanks
react-native-qrcode-generator
Can anyone give me suggestions on how to save this generated QR Code? Any help much appreciated
If you want to save the information in QR code as a QR code, you have to convert the QR code into a png image and then store it in your database as an image.
So, what I advise you to do is, when saving, just store the information as a string (or whatever necessary) in the database. When downloading, just retrieve the information from your database and immediately generate the QR Code. It's not consuming a longer time. After the QR Code is generated, then display it.
I think this is the most appropriate solution for you.
You may need react-native-qrcode-generator for generate the QR Code.
Here is a sample code...
You can input key and value (at the top inputs) and press 'Save' button. When the 'Save' button is pressed, you have to store your key-value pair (data) to your database.
Then, input the key (at the bottom input) of which you want to download and press 'Download' button. Then you have to retrieve the data (value) associated with the given key.
State value is set after the value is successfully retrieved from the database. That state is given as a prop to the QRCode component.
import React, { useState } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity, AsyncStorage } from 'react-native';
import QRCode from 'react-native-qrcode-generator';
export default function App() {
const [key, setKey] = useState(null);
const [value, setValue] = useState(null);
const [downloadKey, setDownloadKey] = useState(null);
const [qrCodeValue, setQRCodeValue] = useState('');
const save = async () => {
//You have to implement the function that saves your information into your database.
//Here I'm saving data to AsyncStorage. (For sample)
await AsyncStorage.setItem(key, value);
}
const download = async () => {
//You have to implement the function that retrieves your information from your database for given key.
//Here I'm retrieving data from AsyncStorage. (For sample)
const qrValue = await AsyncStorage.getItem(downloadKey);
setQRCodeValue(qrValue);
}
return (
<View style={styles.container}>
<View style={styles.row}>
<TextInput placeholder={'Key'} value={key} onChangeText={(key) => setKey(key)} style={styles.textInput}/>
<TextInput placeholder={'Value'} value={value} onChangeText={(value) => setValue(value)} style={styles.textInput}/>
</View>
<TouchableOpacity style={{ flexDirection: 'row', marginBottom: 50 }} onPress={save}>
<Text style={styles.button}>Save</Text>
</TouchableOpacity>
{qrCodeValue ? <QRCode value={qrCodeValue} size={200} /> : null}
<Text style={{ margin: 10 }}>{qrCodeValue}</Text>
<View style={[styles.row, { marginTop: 50 }]}>
<TextInput placeholder={'Key'} value={downloadKey} onChangeText={(downloadKey) => setDownloadKey(downloadKey)} style={styles.textInput}/>
<TouchableOpacity style={{ flex: 1, flexDirection: 'row' }} onPress={download}>
<Text style={styles.button}>Download</Text>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
paddingTop: 50,
paddingBottom: 50
},
row: {
flexDirection: 'row',
},
textInput: {
flex: 1,
borderColor: '#808080',
borderWidth: 1,
borderRadius: 5,
margin: 5,
paddingLeft: 5,
paddingRight: 5,
},
button: {
flex: 1,
borderColor: '#0040FF',
backgroundColor: '#0080FF',
borderWidth: 1,
borderRadius: 5,
margin: 5,
textAlign: 'center',
textAlignVertical: 'center',
height: 30
},
});
Here is a Demo...
Please go through this and feel free to ask me if you have any further problems. Good luck!
You can use rn-qr-generator to generate a QR code with a given string value. It will return a path or base64 representation of the image. Later you can use CameraRoll to save the the image.
import RNQRGenerator from 'rn-qr-generator';
RNQRGenerator.generate({
value: 'string_value',
height: 100,
width: 100,
base64: false,
backgroundColor: 'black',
color: 'white',
})
.then(response => {
const { uri, width, height, base64 } = response;
})
.catch(error => console.log('Error creating QR code image', error));
If you want to save the QR Code as an image to your device, you should convert the QRcode view component into a png image and then store it.
You may use react-native-view-shot to convert the QRcode view component into a png image and rn-fetch-blob to save the image to your gallery.

How to change props of TextInput component in a FlatList?

I'm a newbie in React Native.
What I'm trying to do is making a Google Maps-like app. At the MainMap.js screen, when we enter,the screen will immediately generate 2 search bars. The first one will have the text "Your location". The second one and so on will be empty for users to type in for searching location.
But, I'm having some problems with the FlatList component. In my PlaceInput component, I use the defaultValue, as a prop, for the text input. And then in the MainMap.js, I will have a state which initially be set as "Your Location", then I'll change it to null when the FlatList starts rendering from the 2nd PlaceInput component.
Here's the MainMap.js*
import React from 'react';
import {
TouchableWithoutFeedback,
StyleSheet,
Keyboard,
PermissionsAndroid,
Platform,
View,
Button,
FlatList,
Dimensions
} from 'react-native';
import PlaceInput from '../components/PlaceInput';
import axios from 'axios';
import PolyLine from '#mapbox/polyline';
import MapView, {Polyline, Marker} from 'react-native-maps';
import Geolocation from 'react-native-geolocation-service';
const INCREMENT = 1;
const HEIGHT = Dimensions.get('window').height;
const WIDTH = Dimensions.get('window').width;
class MainMap extends React.Component{
constructor(props){
super(props);
this.state={
_userLocationDisplayed: null,
userLatitude: 0,
userLongitude: 0,
numOfInput:[0,1],
counter: 1,
};
};
componentDidMount(){
this._requestUserLocation();
};
// Get user current location
// Ask user permission for current location
// Request the Directions API from Google
// Get the formatted_address & name from Google Places API
// Adding a search bar
onAddSearch(){
this.setState((state) => ({
counter: state.counter + INCREMENT,
numOfInput: [...state.numOfInput, state.counter],
}));
};
onChangeSearchDisplay(){
this.setState({
_userLocationDisplayed: null
})
};
render(){
return(
<TouchableWithoutFeedback onPress={this.hideKeyboard} >
<View style={styles.container} >
<View style={{height: HEIGHT/2.5 }}>
<FlatList
data={this.state.numOfInput}
keyExtractor={(item, index) => item}
renderItem={itemData => {
return(
<PlaceInput
id={itemData.item}
onDelete={this.onDeleteSearch}
showDirectionOnMap={this.showDirectionOnMap}
userLatitude={userLatitude}
userLongitude={userLongitude}
userLocationDisplayed={this.state._userLocationDisplayed}
/>
)
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
)
}
}
//}
export default MainMap;
const styles = StyleSheet.create({
container:{
flex: 1
},
map:{
...StyleSheet.absoluteFillObject
},
});
Here's the PlaceInput component
import React from 'react';
import {
View,
TextInput,
StyleSheet,
Text,
Dimensions,
TouchableOpacity,
Keyboard,
} from 'react-native';
import axios from 'axios';
import _ from 'lodash'
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
const WIDTH = Dimensions.get('window').width;
const HEIGHT = Dimensions.get('window').height;
class PlaceInput extends React.Component{
constructor(props){
super(props);
this.state={
...
}
...
}
render() {
// console.log(this.state);
// Code for displaying the suggestions from the Google Place API
// Don't care about it too much :)))
const predictions = this.state.predictions.map(prediction => {
const { id, structured_formatting, place_id } = prediction;
return(
<TouchableOpacity
key={id}
onPress={() => this.setDestination(structured_formatting.main_text, place_id)}
>
<View style={styles.suggestion}>
<Text style={styles.mainText}>{structured_formatting.main_text}</Text>
<Text style={styles.secText}>{structured_formatting.secondary_text}</Text>
</View>
</TouchableOpacity>
);
} )
return (
<View style={{flex: 1, flexDirection: 'column'}} key={this.props.id}>
<View style={styles.buttonContainer}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{fontSize: 8}}>{'\u25A0'}</Text>
</View>
<View style={{flex: 4}}>
<TextInput
key={this.id}
autoCorrect={false}
autoCapitalize='none'
style={styles.inputStyle}
placeholder='Search your places'
onChangeText={(input) => {
this.setState({destinationInput: input});
this.getPlacesDebounced(input);
}}
value={this.state.destinationInput}
{/*What I'm trying here as mentioned*/}
defaultValue={this.props.userLocationDisplayed}
/>
</View>
<View style={styles.rightCol}>
<TouchableOpacity onPress={() => this.props.onDelete(this.props.id)}>
<Icon name='delete' size={25} style={{alignSelf: 'center'}} />
</TouchableOpacity>
</View>
</View>
{predictions}
</View>
)
}
}
const styles = StyleSheet.create({
buttonContainer:{
flexDirection: 'row',
height: (HEIGHT - 690),
width: (WIDTH-48),
marginTop: 55,
padding: 5,
backgroundColor: 'white',
shadowColor: '#000000',
elevation: 7,
shadowRadius: 5,
shadowOpacity: 1,
borderRadius: 5,
alignItems: 'center',
alignSelf:'center'
},
inputStyle:{
fontFamily: 'sans-serif-thin',
fontSize: 16,
color: 'black',
fontWeight: 'bold'
},
suggestion:{
backgroundColor: 'white',
padding: 10,
borderWidth: 0.5,
width: (WIDTH-48),
alignSelf: 'center'
},
secText:{
color: '#777'
},
mainText:{
color: '#000'
},
rightCol:{
flex: 1,
borderLeftWidth: 1,
borderColor: '#ededed',
},
})
export default PlaceInput;
I'd love to hear your comments for helping me.
Also, feel free to give out other ways too since I think my way isn't optimized enough. And I'm building this for production too.
If I understand your question correctly, you're asking how to conditionally set a prop value based upon where it is in the flatlist data. Basically you want the first PlaceInput component to have a displayed "entered" text value of "Your Location" and the rest to have nothing.
Update API of PlaceInput to take in another prop to indicate displaying a default value or not.
PlaceInput.js
...
<TextInput
key={this.id}
autoCorrect={false}
autoCapitalize='none'
style={styles.inputStyle}
placeholder='Search your places'
onChangeText={(input) => {
this.setState({destinationInput: input});
this.getPlacesDebounced(input);
}}
value={this.state.destinationInput}
defaultValue={this.props.displayDefaultValue ? this.props.defaultValue : null}
/>
...
And pass in whether or not any specific PlaceInput should display it or not. Since you want only the first to display and the rest to not, using the array index is a good place to start. Here we can leverage the fact that in javascript 0 is a falsey value, while all other numbers are truthy. Using !index then !0 is true while !1, !2, etc, are all false.
MainMap.js
<FlatList
data={this.state.numOfInput}
keyExtractor={(item, index) => item}
renderItem={({ index, item }) => {
return(
<PlaceInput
id={item}
defaultValue="Your Location"
displayDefaultValue={!index} // index 0 is falsey, all others truthy
onDelete={this.onDeleteSearch}
showDirectionOnMap={this.showDirectionOnMap}
userLatitude={userLatitude}
userLongitude={userLongitude}
userLocationDisplayed={this.state._userLocationDisplayed}
/>
)
}}
/>
I take advantage of Drew Reese's answer but It doesn't work
I found out why it doesn't work because of the value prop, whose value is set by this.state.destinationInput which is " " in the state in the constructor. I again use Drew's way in the value prop instead, and it works
<TextInput
key={this.id}
autoCorrect={false}
autoCapitalize='none'
style={styles.inputStyle}
placeholder='Search your places'
onChangeText={(input) => {
this.setState({destinationInput: input});
this.getPlacesDebounced(input);
}}
value={this.props.displayDefaultValue ? this.props.defaultValue : this.state.destinationInput}
/>
BIG thanks to Drew Reese

Attempting to create an object of type with an existing primary key value 'not implemented'

I'm trying to store user email address in Realm whenever the user hits Submit but whenever I do so, I'm getting the error (link below). I understand that data persists in realm and every time I render, I'm trying to create a new Email object with the same name.
I followed https://realm.io/docs/javascript/latest/#updating-objects (the update section). Maybe updating will do the trick to fix this issue? realm.write() method is what I'm focusing on.
error I'm getting
Here's my .js file:
import React, { Component } from 'react';
import {TextInput, KeyboardAvoidingView, Text, StyleSheet, TouchableOpacity} from 'react-native';
import Third from './Third';
class Second extends Component {
onButtonPress() {
this.props.navigator.push({
id: 'Third' // .js file name
});
}
render() {
const Realm = require('realm');
class Email {}
Email.schema = {
name: 'Email',
primaryKey: 'name',
properties: {
name: 'string',
},
};
const realm = new Realm({schema: [Email]});
// Query
let email = realm.objects('Email');
// email.length // => 0
// Write
realm.write(() => {
email = realm.create('Email', {
name: 'something'
});
realm.create('Email', {name: "else"}, true);
});
return(
<KeyboardAvoidingView style={styles.container}>
<TextInput
style={styles.userInput}
placeholder={" email"}
/>
<TextInput
style={styles.userInput}
placeholder={" password"}
secureTextEntry={true}
/>
<TouchableOpacity style={styles.buttonContainer}>
<Text onPress={this.onButtonPress.bind(this)} style={styles.buttonText}>Submit</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20 // makes button horizontally longer.
},
userInput: {
marginBottom: 20,
height: 40,
borderWidth: 4
},
userInput: {
marginBottom: 20,
backgroundColor: '#9b42f4',
height: 40,
borderRadius: 10,
borderWidth: 1
},
buttonContainer: {
backgroundColor: '#41bbf4',
paddingVertical: 10,
marginBottom: 20,
borderRadius: 10
},
buttonText: {
textAlign: 'center',
color: '#FFFFFF'
}
});
export default Second;

Categories

Resources