I have a realm database in my React Native Project. I want to update the value of the language in another page. I was able to write the value initially but am I Am stuck updating it. Below is my code.
Profile Schema (Realm Database Schema)
'use strict';
import Realm from 'realm';
class Profile extends Realm.Object {}
Profile.schema = {
name: 'Profile',
properties: {
Onetime: 'string',
Name: 'string',
Email: 'string',
Phone: 'string',
Language:'string',
Url:'string',
},
};
export default new Realm({schema: [Profile]});
Loading Initial Data
let objects = realm.objects('Profile');
var name,url,phone,onetime;
if (firebase.auth().currentUser.displayName == null ) {
onetime= 'true';
name= 'Name';
url = 'https://media2.giphy.com/media/sbLpwwHlgls8E/giphy.gif';
phone = '0000000000';
}
else {
onetime= 'true';
name=firebase.auth().currentUser.displayName;
url=firebase.auth().currentUser.photoURL;
phone = '0000000000';
}
if (objects.length == 0) {
realm.write(() => {
realm.create('Profile', { Onetime: onetime, Name: name, Email: firebase.auth().currentUser.email, Phone:phone, Language: 'e', Url: url, });
});
}
else {
realm.write(() => {
realm.delete(objects);
realm.create('Profile', { Onetime: onetime, Name: name, Email: firebase.auth().currentUser.email, Phone:phone, Language: 'e', Url: url, });
});
}
Activity where I have to update the value
import React from 'react';
import {
ScrollView,
View,
StyleSheet
} from 'react-native';
import {
RkText,
RkTextInput,
RkAvoidKeyboard,
RkTheme,
RkStyleSheet
} from 'react-native-ui-kitten';
import {SocialSetting} from '../../components';
import {FontAwesome} from '../../assets/icons';
import {GradientButton} from '../../components';
import Avatar from 'react-native-interactive-avatar';
import ImagePicker from 'react-native-image-crop-picker';
import realm from '../../realm';
import firebase from 'firebase';
import {RkSwitch} from '../../components/switch/index';
import RadioForm, {RadioButton, RadioButtonInput, RadioButtonLabel} from 'react-native-simple-radio-button';
var radio_props = [
{label: 'English ', value: 'e' },
{label: 'Malayalam', value: 'm'}
];
var lange = '';
var objects = realm.objects('Profile');
export class ProfileSettings extends React.Component {
static navigationOptions = {
title: 'Profile Settings'.toUpperCase()
};
constructor(props) {
super(props);
this.state = {
name: objects[0].Name,
email: objects[0].Email,
phone: objects[0].Phone,
language:objects[0].Language,
url:objects[0].Url,
lang:''
}
}
pickimage(){
ImagePicker.openPicker({
width: 300,
height: 400,
cropping: true
}).then(image => {
console.log("imagelink- "+image);
});
}
handleLogOut() {
firebase.auth().signOut();
}
handleSave() {
alert("Language is: "+lange);
}
updateuser(){
var user = firebase.auth().currentUser;
user.updateProfile({
displayName: this.state.name,
email: this.state.email
}).then(function() {
alert("Update SuccessFull");
}).catch(function(error) {
// An error happened.
alert("Update Failed");
});
}
render() {
if (this.state.language == 'e') {
var val = 0;
}
else {
var val = 1;
}
return (
<ScrollView style={styles.root}>
<RkAvoidKeyboard>
<View style={styles.header}>
<Avatar
uri={this.state.url}
size={'default'}
/>
</View>
<View style={styles.section}>
<View style={[styles.row, styles.heading]}>
<RkText rkType='header6 primary'>INFO</RkText>
</View>
<View style={styles.row}>
<RkTextInput label='Name'
value={this.state.name}
rkType='right clear'
onChangeText={(text) => this.setState({name: text})}/>
</View>
<View style={styles.row}>
<RkTextInput label='Email'
value={this.state.email}
onChangeText={(text) => this.setState({email: text})}
rkType='right clear'/>
</View>
</View>
<View style={styles.section}>
<View style={[styles.row, styles.heading]}>
<RkText rkType='primary header6'>CHOOSE YOUR LANGUAGE</RkText>
</View>
<View>
<View style={styles.radio}>
<RadioForm
radio_props={radio_props}
initial={val}
onPress={(value) => {
{
this.setState({lang:value})
this.setState({language: this.state.lang})
lange = value;
}}}
/>
</View>
</View>
</View>
<GradientButton rkType='large' style={styles.button} text='SAVE' onPress={this.handleSave} />
<GradientButton rkType='large' style={styles.button} text='LOGOUT' onPress={this.handleLogOut}/>
</RkAvoidKeyboard>
</ScrollView>
)
}
}
let styles = RkStyleSheet.create(theme => ({
root: {
backgroundColor: theme.colors.screen.base
},
header: {
backgroundColor: theme.colors.screen.neutral,
paddingVertical: 25,
justifyContent: 'center',
alignItems: 'center'
},
section: {
marginVertical: 25
},
radio: {
flexDirection:'row',
margin:20
},
heading: {
paddingBottom: 12.5
},
row: {
flexDirection: 'row',
paddingHorizontal: 17.5,
marginTop:15,
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: theme.colors.border.base,
alignItems: 'center',
justifyContent: 'space-between',
flex:1
},
button: {
marginHorizontal: 16,
marginBottom: 32
}
}));
I want to update the value of language in the handleSave()
Any help would be highly appreciated.
Thanks in Advance.
Solved the problem. Here is the solution
handleSave() {
//alert("Language is: "+lange);
let updt = realm.objects('Profile');
realm.write(() => {
updt[0].Language = lange;
});
alert("Language is: "+updt[0].Language);
}
Just create an object of the schema and update the value of the particular field.
Related
Here I have used Redux to manage state but i am getting this type of Error: TypeError: navigation.state.params.AddBlack is not a function. (In 'navigation.state.params.AddBlack({
noteTitle: noteTitle,
noteValue: noteValue
})', 'navigation.state.params.AddBlack' is undefined)
ViewBlacks.js
import React from 'react'
import { Button, StyleSheet, View, FlatList } from 'react-native'
import { Text, FAB, List } from 'react-native-paper'
import { useSelector, useDispatch } from 'react-redux'
import { addblack, deleteblack } from '../redux/notesApp'
import Header from '../components/Header'
function ViewBlacks({ navigation }) {
const blacks = useSelector(state => state.number)
const dispatch = useDispatch()
const addBlack = black => dispatch(addblack(black))
const deleteBlack = id => dispatch(deleteblack(id))
return (
<>
<Header titleText='Simple Note Taker' />
<Button title="Go back" onPress={() => navigation.goBack()} />
<View style={styles.container}>
{blacks.length === 0 ? (
<View style={styles.titleContainer}>
<Text style={styles.title}>You do not have any notes</Text>
</View>
) : (
<FlatList
data={blacks}
renderItem={({ item }) => (
<List.Item
title={item.black.noteTitle}
description={item.black.noteValue}
descriptionNumberOfLines={1}
titleStyle={styles.listTitle}
onPress={() => deleteBlack(item.id)}
/>
)}
keyExtractor={item => item.id.toString()}
/>
)}
<FAB
style={styles.fab}
small
icon='plus'
label='Add new note'
onPress={() =>
navigation.navigate('AddBlacks', {
addBlack
})
}
/>
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 10,
paddingVertical: 20
},
titleContainer: {
alignItems: 'center',
justifyContent: 'center',
flex: 1
},
title: {
fontSize: 20
},
fab: {
position: 'absolute',
margin: 20,
right: 0,
bottom: 10
},
listTitle: {
fontSize: 20
}
})
export default ViewBlacks
AddBlack.js
import React, { useState } from 'react'
import { View, StyleSheet } from 'react-native'
import { IconButton, TextInput, FAB } from 'react-native-paper'
import Header from '../components/Header'
function AddBlack({ navigation }) {
const [noteTitle, setNoteTitle] = useState('')
const [noteValue, setNoteValue] = useState('')
function onSaveNote() {
navigation.state.params.addBlack({ noteTitle, noteValue })
navigation.goBack()
}
return (
<>
<Header titleText='Add a new note' />
<IconButton
icon='close'
size={25}
color='white'
onPress={() => navigation.goBack()}
style={styles.iconButton}
/>
<View style={styles.container}>
<TextInput
label='Add Title Here'
value={noteTitle}
mode='outlined'
onChangeText={setNoteTitle}
style={styles.title}
/>
<TextInput
label='Add Note Here'
value={noteValue}
onChangeText={setNoteValue}
mode='flat'
multiline={true}
style={styles.text}
scrollEnabled={true}
returnKeyType='done'
blurOnSubmit={true}
/>
<FAB
style={styles.fab}
small
icon='check'
disabled={noteTitle == '' ? true : false}
onPress={() => onSaveNote()}
/>
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 20,
paddingVertical: 20
},
iconButton: {
backgroundColor: 'rgba(46, 113, 102, 0.8)',
position: 'absolute',
right: 0,
top: 40,
margin: 10
},
title: {
fontSize: 24,
marginBottom: 20
},
text: {
height: 300,
fontSize: 16
},
fab: {
position: 'absolute',
margin: 20,
right: 0,
bottom: 0
}
})
export default AddBlack
notesReducer.js
import remove from 'lodash.remove'
// Action Types
export const ADD_NOTE = 'ADD_NOTE'
export const DELETE_NOTE = 'DELETE_NOTE'
export const ADD_BLACK = 'ADD_BLACK'
export const DELETE_BLACK = 'DELETE_BLACK'
// Action Creators
let noteID = 0
let blackID = 0
export function addnote(note) {
return {
type: ADD_NOTE,
id: noteID++,
note
}
}
export function deletenote(id) {
return {
type: DELETE_NOTE,
payload: id
}
}
export function addblack(black) {
return {
type: ADD_BLACK,
id: blackID++,
black
}
}
export function deleteblack(id) {
return {
type: DELETE_BLACK,
payload: id
}
}
// reducer
const INITIAL_STATE = {
note: [], // for holds notes
number: [] // for holds numbers
};
function notesReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case ADD_NOTE:
return {
...state,
note: [
...state.note,
{
id: action.id,
note: action.note
}
]
};
case DELETE_NOTE:
const note = remove(state.note, obj => obj.id != action.payload);
return {...state, note};
case ADD_BLACK:
return {
...state,
number: [
...state.number,
{
id: action.id,
number: action.number
}
]
};
case DELETE_BLACK:
const number = remove(state.number, obj => obj.id != action.payload);
return {...state, number}
default:
return state
}
}
export default notesReducer
I have a problem, when I do a search, I get the data from my API, the first time I do a search, everything is fine, all the data is displayed. However, when I do a second search immediately, nothing is updated.
I put in console.log, and I see that I'm getting this data back, yet the display is not updated.
import React, { Component } from "react";
import { SafeAreaView, StyleSheet } from "react-native";
import Search from "./Component/Search";
export default class App extends Component {
render() {
return (
<SafeAreaView style={styles.container}>
<Search />
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
import React from "react";
import { View, TextInput, Button, FlatList, StyleSheet } from "react-native";
import LivreItem from "../Component/LivreItem";
class Search extends React.Component {
constructor(props) {
super(props);
this.inputValue = "";
this.state = { livres: [] };
}
searchBooks = async () => {
const key = "&key=XXXXXXXXXXXXXXXXXXXXXXX";
const url = "https://www.googleapis.com/books/v1/volumes?q=" + this.inputValue + key;
return fetch(url)
.then(response => response.json())
.catch(e => {
console.log("Une erreur s'est produite");
console.log(e);
});
};
getBooks = () => {
if (this.inputValue.length > 0) {
this.searchBooks()
.then(data => this.setState({ livres: data.items }))
.catch(reject => console.log(reject));
}
};
changeText = text => {
this.inputValue = text;
};
render() {
return (
<View style={styles.header_container}>
<View style={styles.sub_container}>
<TextInput
onChangeText={text => this.changeText(text)}
style={styles.input}
placeholder="Ex: Harry Potter"
/>
<Button
style={styles.button}
title="Rechercher"
onPress={() => this.getBooks()}
/>
</View>
<FlatList
style={styles.list}
data={this.state.livres}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <LivreItem livre={item.volumeInfo} />}
/>
</View>
);
}
}
const styles = StyleSheet.create({
sub_container: {
justifyContent: "space-between",
flexDirection: "row",
marginTop: 30,
paddingRight: 10,
paddingLeft: 10
},
header_container: {
flex: 1,
flexDirection: "column",
padding: 10
},
input: {
borderRadius: 4,
borderWidth: 0.5,
borderColor: "#d6d7da",
width: 150,
paddingLeft: 5
},
button: {
borderRadius: 4
},
list: {
paddingLeft: 15,
paddingRight: 15
}
});
export default Search;
import React from "react";
import { View, StyleSheet, Image, Text } from "react-native";
class LivreItem extends React.Component {
constructor(props) {
super(props);
this.state = { livre: this.props.livre};
this.description =
this.state.livre.description === null || this.state.livre.description === undefined
? "Pas de description disponible"
: this.state.livre.description;
this.img = this.state.livre.imageLinks;
this.image =
this.img === undefined ||
this.img.smallThumbnail === undefined ||
this.img.smallThumbnail === null
? null
: this.state.livre.imageLinks.smallThumbnail;
}
render() {
return (
<View style={styles.content}>
<View>
<Image style={styles.image} source={{ uri: this.image }} />
<Image style={styles.image} source={this.image} />
</View>
<View style={styles.content_container}>
<Text style={styles.titre}>{this.state.livre.title}</Text>
<Text style={styles.description} numberOfLines={4}>
{this.description}
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
content: {
height: 125,
flexDirection: "row",
marginTop: 15
},
content_container: {
flexDirection: "column",
flexShrink: 1,
marginLeft: 10
},
image: {
width: 100,
height: 100
},
titre: {
fontWeight: "bold",
flexWrap: "wrap"
},
description: {
flexWrap: "wrap"
}
});
export default LivreItem;
Thanks.
Configure the prop extraData in Flatlist component ala:
<FlatList
extraData={this.state.livres}
/>
Pass a boolean value to the FlatList extraData.
<FlatList
extraData={this.state.refresh}
/>
Trying to apply a default query in the reactive search component and it doesn't have an effect
import React from 'react';
import {
NavigationScreenProps,
NavigationScreenConfig, NavigationActions,
} from 'react-navigation';
import {
ChatHeader,
ChatHeaderNavigationStateParams,
} from '#src/components/messaging';
import {
Conversation,
} from '#src/core/model';
import {conversation5} from '#src/core/data/conversation';
import {StyleSheet, Text, Image, TouchableWithoutFeedback} from 'react-native';
import {
ReactiveBase,
DataSearch,
ReactiveList,
} from '#appbaseio/reactivesearch-native';
import {ScrollView, View} from 'react-native';
import {Icon, ListItem} from '#kitten/ui';
import LottieView from 'lottie-react-native';
import {SearchHeader} from '#src/components/search/search.header';
import {userProvider} from '../../../../domain/auth/UserProvider';
import {Screen} from '../../../../core/navigation/screens';
import Tts from 'react-native-tts';
import {StarIconOutline} from '#src/assets/icons';
import axios, {AxiosError, AxiosResponse} from 'axios';
import {Config} from '../../../../constants/Config';
import {User} from '#domain/models';
import DoubleClick from 'react-native-double-tap';
import {Notification} from 'react-native-in-app-message';
import AnimatedLoader from 'react-native-animated-loader';
interface State {
newMessageText: string;
conversation: Conversation;
isLoading: boolean;
message: string;
}
const styles = StyleSheet.create({
container: {
padding: 10,
marginTop: 25,
},
image: {
width: 100,
height: 100,
},
result: {
flexDirection: 'row',
width: '100%',
margin: 5,
alignItems: 'center',
},
notification: {
flexDirection: 'row',
width: '100%',
margin: 5,
padding: 5,
alignItems: 'flex-start',
},
item: {
flexDirection: 'column',
paddingLeft: 10,
},
title: {
fontWeight: 'bold',
},
lottie: {
width: 100,
height: 100,
},
iconx: {
width: 50,
height: 40,
marginLeft: -3,
marginBottom: -10,
padding: 5,
},
notificationText: {
marginTop: 11,
},
});
export class SearchContainer extends React.Component<NavigationScreenProps, State> {
private notification: Notification;
private token: string;
public state: State = {
newMessageText: '',
conversation: conversation5,
isLoading: false,
message: '',
};
private infiniteAnimationIconRef: React.RefObject<Icon> = React.createRef();
static navigationOptions: NavigationScreenConfig<any> = ({navigation, screenProps}) => {
const headerProps: ChatHeaderNavigationStateParams = {
interlocutor: navigation.getParam('interlocutor', conversation5.interlocutor),
lastSeen: navigation.getParam('lastSeen', 'today'),
onBack: navigation.getParam('onBack'),
onProfile: navigation.getParam('onProfile'),
};
const header = (navigationProps: NavigationScreenProps) => {
return (
<SearchHeader
{...navigationProps}
{...headerProps}
/>
);
};
return {...navigation, ...screenProps, header};
};
public async componentWillMount(): void {
this.props.navigation.setParams({
onBack: this.onBackPress,
});
await userProvider.get().then((data) => {
this.token = data.token;
}).catch(() => {
this.props.navigation.navigate(Screen.Login);
});
}
public componentDidMount() {
this.setState({
isLoading: false,
});
}
private onBackPress = (): void => {
this.props.navigation.goBack(null);
};
private say(deText): void {
Tts.setDefaultLanguage('de-DE');
Tts.setDucking(true);
Tts.speak(deText);
}
private star(id): void {
this.setState({isLoading: true});
axios.post(Config.service.stars.url, {
sentence_id: id,
}, {
headers: {
'Authorization': `Bearer ${this.token}`,
},
}).then((response: AxiosResponse<UserData>) => {
this.setState({message: 'Star added!'});
setTimeout(() => this.notification.show(), 100);
this.setState({isLoading: false});
}).catch((error: AxiosError) => {
let errorMessage = null;
try {
const code = error.response.request.status;
if (code === 401) {
this.props.navigation.navigate(Screen.Login);
} else if (code === 422) {
errorMessage = 'Star was added already for this sentence!';
} else {
errorMessage = 'Service is unavailable, please try again in a few!';
}
} catch (e) {
errorMessage = 'Service is unavailable, please try again in a few!';
}
this.setState({...this.state, message: errorMessage});
setTimeout(() => this.notification.show(), 100);
this.setState({isLoading: false});
});
}
public render(): React.ReactNode {
return (
<ReactiveBase
app='myapp'
url='http://xxx.xxxxxx.io'
headers={{'X-Api-Key': 'xxxxxxxxxxxxxxxxxxxxxxxxx'}}>
<View>
<DataSearch
componentId='searchbox'
dataField={[
'sentence',
'sentence.en',
'sentence.de',
'raw.translated',
]}
value='1'
highlight={true}
placeholder='words or expressions'
defaultQuery={() => ({
query: {
match: {
message: {
query: 'test',
},
},
},
})}
autosuggest={false}
/>
</View>
<Notification
customComponent={(
<View style={styles.notification}>
<LottieView
style={styles.iconx}
source={require('#src/animations/warning.json')}
colorFilters={[{
keypath: 'button',
color: '#F00000',
}, {
keypath: 'Sending Loader',
color: '#F00000',
}]}
autoPlay
loop={true}
/>
<Text style={styles.notificationText}>{this.state.message}</Text>
</View>
)}
ref={(c) => this.notification = c}
/>
<AnimatedLoader
visible={this.state.isLoading}
overlayColor='rgba(255,255,255,0.75)'
source={require('#src/animations/loader.json')}
animationStyle={styles.lottie}
speed={1}
/>
<ScrollView
stickyHeaderIndices={[1]}
nativeID={'scoller'}
>
<View>
<ReactiveList
componentId='results'
dataField='sentence.de'
size={7}
showResultStats={false}
pagination={true}
infiniteScroll={true}
scrollTarget={'scroller'}
react={{
and: 'searchbox',
}}
defaultValue={'Harry Potter'}
onData={(res, idx) => (
<View style={styles.result} key={res._id}>
<DoubleClick
singleTap={() => {
this.star(res._id);
}}
doubleTap={() => {
}}
delay={1000}
>
<Icon name='star-outline' fill='#FF9999' width='30' height='50'/>
</DoubleClick>
<ListItem
onPress={() => this.say(res.sentence.de)}
title={res.sentence.de}
description={res.raw.translated}
/>
</View>
)}
/>
</View>
</ScrollView>
</ReactiveBase>
);
}
}
<DataSearch
componentId='searchbox'
dataField={[
'sentence',
'sentence.en',
'sentence.de',
'raw.translated',
]}
value='1'
highlight={true}
placeholder='words or expressions'
defaultQuery={() => ({
query: {
match: {
message: {
query: 'test',
},
},
},
})}
autosuggest={false}
/>
Try this (i.e. use filter instead of should):
<ReactiveComponent
componentId='filterbox'
customQuery={props => ({
query: {
'bool': {
'filter': [{
'ids': {
'type': 'mydoctype',
'values': ['TK6IRm4BK9UoLvJay0OC', 'Ra6IRm4BK9UoLvJaykMD'],
},
}]
},
}
})}
/>
I create a component Confirm.js with react-native <Modal /> that has two DropDownMenu and two <Button />.
I want user click the Yes <Button /> than i can get the DropDownMenu onOptionSelected value. I think i should use this.props but i have no idea how to do it.
I want get the value in MainActivity.js from Confirm.js
Any suggestion would be appreciated. Thanks in advance.
Here is my MainActivty.js click the <Button /> show <Confirm />:
import React, { Component } from 'react';
import { Confirm } from './common';
import { Button } from 'react-native-elements';
class MainActivity extends Component {
constructor(props) {
super(props);
this.state = { movies: [], content: 0, showModal: false, isReady: false };
}
// close the Confirm
onDecline() {
this.setState({ showModal: false });
}
render() {
return (
<View style={{ flex: 1 }}>
<Button
onPress={() => this.setState({ showModal: !this.state.showModal })}
backgroundColor={'#81A3A7'}
containerViewStyle={{ width: '100%', marginLeft: 0 }}
icon={{ name: 'search', type: 'font-awesome' }}
title='Open the confirm'
/>
<Confirm
visible={this.state.showModal}
onDecline={this.onDecline.bind(this)}
>
</Confirm>
</View>
);
}
}
export default MainActivity;
Confirm.js:
import React from 'react';
import { Text, View, Modal } from 'react-native';
import { DropDownMenu } from '#shoutem/ui';
import TestConfirm from './TestConfirm';
import { CardSection } from './CardSection';
import { Button } from './Button';
import { ConfirmButton } from './ConfirmButton';
const Confirm = ({ children, visible, onAccept, onDecline }) => {
const { containerStyle, textStyle, cardSectionStyle } = styles;
return (
<Modal
visible={visible}
transparent
animationType="slide"
onRequestClose={() => {}}
>
<View style={containerStyle}>
<CardSection style={cardSectionStyle}>
{/* Here is my DropDownMenu */}
<TestConfirm />
</CardSection>
<CardSection>
<ConfirmButton onPress={onAccept}>Yes</ConfirmButton>
<ConfirmButton onPress={onDecline}>No</ConfirmButton>
</CardSection>
</View>
</Modal>
);
};
const styles = {
cardSectionStyle: {
justifyContent: 'center'
},
textStyle: {
flex: 1,
fontSize: 18,
textAlign: 'center',
lineHeight: 40
},
containerStyle: {
backgroundColor: 'rgba(0, 0, 0, 0.75)',
position: 'relative',
flex: 1,
justifyContent: 'center'
},
buttonStyle: {
flex: 1,
alignSelf: 'stretch',
backgroundColor: '#fff',
borderRadius: 5,
borderWidth: 1,
borderColor: '#007aff',
marginLeft: 5,
marginRight: 5
}
};
export { Confirm };
TestConfirm.js
import React, { Component } from 'react';
import { View } from 'react-native';
import { DropDownMenu, Title, Image, Text, Screen, NavigationBar } from '#shoutem/ui';
import {
northCities,
centralCities,
southCities,
eastCities,
islandCities
} from './CityArray';
class TestConfirm extends Component {
constructor(props) {
super(props);
this.state = {
zone: [
{
id: 0,
brand: "North",
children: northCities
},
{
id: 1,
brand: "Central",
children: centralCities
},
{
id: 2,
brand: "South",
children: southCities
},
{
id: 3,
brand: "East",
children: eastCities
},
{
id: 4,
brand: "Island",
children: islandCities
},
],
}
}
render() {
const { zone, selectedZone, selectedCity } = this.state
return (
<Screen>
<DropDownMenu
style={{
selectedOption: {
marginBottom: -5
}
}}
styleName="horizontal"
options={zone}
selectedOption={selectedZone || zone[0]}
onOptionSelected={(zone) =>
this.setState({ selectedZone: zone, selectedCity: zone.children[0] })}
titleProperty="brand"
valueProperty="cars.model"
/>
<DropDownMenu
style={{
selectedOption: {
marginBottom: -5
}
}}
styleName="horizontal"
options={selectedZone ? selectedZone.children : zone[0].children} // check if zone selected or set the defaul zone children
selectedOption={selectedCity || zone[0].children[0]} // set the selected city or default zone city children
onOptionSelected={(city) => this.setState({ selectedCity: city })} // set the city on change
titleProperty="cnCity"
valueProperty="cars.model"
/>
</Screen>
);
}
}
export default TestConfirm;
If i console.log DropDownMenu onOptionSelected value like the city it would be
{cnCity: "宜蘭", enCity: "Ilan", id: 6}
I want to get the enCity from MainActivity.js
ConfirmButton.js:
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
const ConfirmButton = ({ onPress, children }) => {
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
);
};
const styles = {
{ ... }
};
export { ConfirmButton };
You can pass a function to related component via props and run that function with the required argument you got from the dropdowns. Because you have couple of components in a tree it is going to be a little hard to follow but if you get the idea I'm sure you'll make it simpler. Also after getting comfortable with this sort of behavior and react style coding you can upgrade your project to some sort of global state management like redux, flux or mobx.
Sample (removed unrelated parts)
class MainActivity extends Component {
onChangeValues = (values) => {
// do some stuf with the values
// value going to have 2 properties
// { type: string, value: object }
const { type, value } = values;
if(type === 'zone') {
// do something with the zone object
} else if(type === 'city') {
// do something with the city object
}
}
render() {
return(
<Confirm onChangeValues={this.onChangeValues} />
)
}
}
const Confirm = ({ children, visible, onAccept, onDecline, onChangeValues }) => {
return(
<TestConfirm onChangeValues={onChangeValues} />
)
}
class TestConfirm extends Component {
render() {
return(
<Screen>
<DropDownMenu
onOptionSelected={(zone) => {
// run passed prop with the value
this.props.onChangeValues({type: 'zone', value: zone});
this.setState({ selectedZone: zone, selectedCity: zone.children[0] });
}}
/>
<DropDownMenu
onOptionSelected={(city) => {
// run passed prop with the value
this.props.onChangeValues({type: 'city', value: city});
this.setState({ selectedCity: city })
}}
/>
</Screen>
)
}
}
Basically what i'm trying to do is, on click of login button it should take my input data and check whether the data is valid for authentication and send back response to user and display on UI. After authentication it should be redirected to home screen. I tried using fetch but it's not working. Below is the code:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
Image,
View,
StyleSheet,
TextInput,
Linking,
Alert,
Navigator
} from 'react-native';
import { Button } from 'react-native-elements';
import t from 'tcomb-form-native';
const Form = t.form.Form;
// here we are: define your domain model
const Email = t.subtype(t.Str, (email) => {
const reg = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return reg.test(email);
});
const LoginFields = t.struct({
username: Email, // a required string
password: t.String, // a required string
});
const options = {
fields: {
password: {
type: 'password',
placeholder: 'Password',
error: 'Password cannot be empty'
},
username: {
placeholder: 'e.g: abc#gmail.com',
error: 'Insert a valid email'
}
}
}; // optional rendering options (see documentation)
export class ChildComponent extends Component {
render() {
if(this.props.result) {
var res = this.props.result.map((item, i) => {
return(
<Text key={i}>{item.useremail}</Text>
)
})
}
return (
<View>
{res}
</View>
)
}
}
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
buttonState: true,
value: {}
}
}
_onSubmit() {
const value = this.refs.form.getValue();
if (value) { // if validation fails, value will be null
console.log(value);
// value here is an instance of LoginFields
}
componentDidMount() {
fetch('http://192.168.100.160:6016/admin/login', {
method: 'POST',
headers: {
'Accept': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify({
useremail: 'kirti#pws.com',
userpassword: '1234',
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState ({
data: responseJson.admin/login
})
})
}
this.props.navigator.push({
id: 'Home'
});
}
onChange = () => {
const value = this.refs.form.getValue();
if(value) {
this.setState({
value,
buttonState: false
});
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
</View>
<View style={styles.content}>
<Text style={styles.contentHeader}>
Pateast Login
</Text>
<View style={styles.loginFormContent}>
<Form
ref="form"
type={LoginFields}
options={options}
value={this.state.value}
onChange={this.onChange}
/>
<Text style={{color: 'blue', marginBottom: 10}}
onPress={() => Linking.openURL('https://www.google.co.in')}>
Forgot Password?
</Text>
<Button
raise
icon={{name: 'key', type: 'octicon'}}
onPress={this._onSubmit.bind(this)}
title="Login"
disabled={this.state.buttonState}
accessibilityLabel="Ok, Great!"
/>
</View>
</View>
<View style={styles.footer}>
</View>
<ChildComponent status={this.state.status} result={this.state.data} />
</View>
);
}
}
const styles = StyleSheet.create(
{
container: {
flex: 1
},
contentHeader: {
// fontFamily: 'sans-serif-condensed',
fontWeight: 'bold',
fontSize: 40,
alignSelf: 'center',
marginBottom: 30
},
header : {
flex: 0.5,
backgroundColor: '#008080'
},
content: {
flex: 10,
backgroundColor: '#f8f8ff',
justifyContent: 'center'
},
loginFormContent: {
marginHorizontal: 20
},
footer: {
flex: 0.5,
backgroundColor: '#008080'
},
loginText: {
fontSize: 20,
marginBottom: 10
},
inputFields: {
fontSize: 20,
borderStyle: 'solid',
borderColor: '#000000',
borderRadius: 30,
marginBottom: 10
}
}
);
you were just one step away from your goal. The only thing you have to change is your body object in your post request. This object has to be a FormData https://developer.mozilla.org/de/docs/Web/API/FormData
Try to set the body like this:
let data = new FormData();
data.append("useremail", 'kirti#pws.com');
data.append("userpassword", '1234');
After that your fetch request should look like this:
fetch('http://192.168.100.160:6016/admin/login', {
method: 'POST',
headers: {
'Accept': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: data
}
...