React Native navigator ref property - facebook

I am trying to follow the example (https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/Navigator) on the react native site to set up my navigator, but I can't seem to get it to work. Right now I am having trouble with the ref property, as when its calls _setNavigatorRef, I am getting an error that it cannot find the property _navigator of null in the following code. It works in the example but I am not sure why:
index.ios.js
'use strict';
var React = require('react-native');
var DataEntry = require('./app/DataEntry');
var PasswordView = require('./app/PasswordView');
var GoogSignIn = require('./app/GoogSignIn');
var {
AppRegistry,
Image,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} = React;
class PasswordRecovery extends React.Component {
render() {
return (
<Navigator
ref={this._setNavigatorRef}
style={styles.container}
initialRoute={{id: 'GoogSignIn', name: 'Index'}}
renderScene={this.renderScene}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromRight;
}} />
);
}
renderScene(route, navigator) {
switch (route.id) {
case 'GoogSignIn':
return <GoogSignIn navigator={navigator} />;
case 'DataEntry':
return <DataEntry navigator={navigator} />;
case 'PasswordView':
return <PasswordView navigator={navigator} />;
default:
return this.noRoute(navigator);
}
noRoute(navigator) {
return (
<View style={{flex: 1, alignItems: 'stretch', justifyContent: 'center'}}>
<TouchableOpacity style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
onPress={() => navigator.pop()}>
<Text style={{color: 'red', fontWeight: 'bold'}}>ERROR: NO ROUTE DETECTED</Text>
</TouchableOpacity>
</View>
);
}
_setNavigatorRef(navigator) {
if (navigator !== this._navigator) {
this._navigator = navigator;
if (navigator) {
var callback = (event) => {
console.log(
`TabBarExample: event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from the owner.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
}
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('PasswordRecovery', () => PasswordRecovery);
I am just trying to get this all setup so that I can display a Google Sign in scene and then navigate from there. The code for that scene so far is here:
GoogSignIn.js
'use strict';
var React = require('react-native');
var { NativeAppEventEmitter } = require('react-native');
var GoogleSignin = require('react-native-google-signin');
var cssVar = require('cssVar');
var { Icon } = require('react-native-icons');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
TouchableHighlight,
PixelRatio,
Navigator,
} = React;
var NavigationBarRouteMapper = {
LeftButton: function(route, navigator, index, navState) {
if (index === 0) {
return null;
}
var previousRoute = navState.routeStack[index - 1];
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.navBarLeftButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
{previousRoute.title}
</Text>
</TouchableOpacity>
);
},
RightButton: function(route, navigator, index, navState) {
return (
null
);
},
Title: function(route, navigator, index, navState) {
return (
<Text style={[styles.navBarText, styles.navBarTitleText]}>
GOOGLE SIGN IN
</Text>
);
},
};
class GoogSignin extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null
};
}
componentWillMount() {
var navigator = this.props.navigator;
var callback = (event) => {
console.log(
`NavigationBarSample : event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from this component.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
componentDidMount() {
this._configureOauth(
'105558473349-7usegucirv10bruohtogd0qtuul3kkhn.apps.googleusercontent.com'
);
}
renderScene(route, navigator) {
console.log("HERE");
return (
<View style={styles.container}>
<TouchableHighlight onPress={() => {this._signIn(); }}>
<View style={{backgroundColor: '#f44336', flexDirection: 'row'}}>
<View style={{padding: 12, borderWidth: 1/2, borderColor: 'transparent', borderRightColor: 'white'}}>
<Icon
name='ion|social-googleplus'
size={24}
color='white'
style={{width: 24, height: 24}}
/>
</View>
<Text style={{color: 'white', padding: 12, marginTop: 2, fontWeight: 'bold'}}>Sign in with Google</Text>
</View>
</TouchableHighlight>
</View>
);
}
render() {
return (
<Navigator
debugOverlay={false}
style={styles.appContainer}
renderScene={this.renderScene}
navigationBar={
<Navigator.NavigationBar
routeMapper={NavigationBarRouteMapper}
style={styles.navBar}/>
}/>
);
}
_configureOauth(clientId, scopes=[]) {
console.log("WE HERE")
GoogleSignin.configure(clientId, scopes);
NativeAppEventEmitter.addListener('googleSignInError', (error) => {
console.log('ERROR signin in', error);
});
NativeAppEventEmitter.addListener('googleSignIn', (user) => {
console.log(user);
this.setState({user: user});
});
return true;
}
_signIn() {
GoogleSignin.signIn();
}
_signOut() {
GoogleSignin.signOut();
this.setState({user: null});
}
};
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
messageText: {
fontSize: 17,
fontWeight: '500',
padding: 15,
marginTop: 50,
marginLeft: 15,
},
button: {
backgroundColor: 'white',
padding: 15,
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
navBar: {
backgroundColor: 'white',
},
navBarText: {
fontSize: 16,
marginVertical: 10,
},
navBarTitleText: {
color: cssVar('fbui-bluegray-60'),
fontWeight: '500',
marginVertical: 9,
},
navBarLeftButton: {
paddingLeft: 10,
},
navBarRightButton: {
paddingRight: 10,
},
navBarButtonText: {
color: cssVar('fbui-accent-blue'),
},
scene: {
flex: 1,
paddingTop: 20,
backgroundColor: '#EAEAEA',
},
});
module.exports = GoogSignin;

I suspect it's a context issue. On your Navigator component, try converting from this:
ref={this._setNavigatorRef}
To this:
ref={(navigator) => this._setNavigatorRef(navigator)} (prettier IMHO)
or this:
ref={this._setNavigatorRef.bind(this)}

Related

Search bar in React Native not updating or filtering

I'm trying to set up data filtering by SearchBar from react-native-elements. I'm returning some data from the server in a JSON format so it arrives in this form of an Array of Objects.
This is what I have so far:
export default function AktList() {
const [akt, setAkt] = useState([]);
const [temp, setTemp] = useState([]);
async function request() {
fetch("http://192.168.5.12:5000/aktprikaz", {
method: "get"
})
.then(res => res.json())
.then(res => setAkt(res))
.then(temp => setTemp(akt));
}
useEffect(() => {
request();
}, []);
function Item({ title, selected }) {
return (
<TouchableOpacity
onPress={() => console.log(temp)}
style={[
styles.item,
{ backgroundColor: selected ? "#6e3b6e" : "#f9c2ff" }
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
function contains(text) {
const newData = temp.filter(item => {
const itemData = {title};
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setAkt(newData);
}
return (
<SafeAreaView style={styles.container}>
<Header />
<SearchBar onChangeText={text => contains(text)} />
<FlatList
data={akt}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
Currently, nor is the text updating nor is it filter anything. I've tried following this tutorial online (tho it is written using classes not functions). What am I doing wrong here?
Check below example which i created using flatlist and TextInput. Items are displayed in the form of a dropdown list when you search items. i think this will help you.
import React, { Component } from 'react';
import { View, Text, FlatList, TextInput, ListItem } from 'react-native';
class FlatListDropDown extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
value: '',
};
this.arrayNew = [
{ name: 'Robert' },
{ name: 'Bryan' },
{ name: 'Vicente' },
{ name: 'Tristan' },
{ name: 'Marie' },
{ name: 'Onni' },
{ name: 'sophie' },
{ name: 'Brad' },
{ name: 'Samual' },
{ name: 'Omur' },
{ name: 'Ower' },
{ name: 'Awery' },
{ name: 'Ann' },
{ name: 'Jhone' },
{ name: 'z' },
{ name: 'bb' },
{ name: 'cc' },
{ name: 'd' },
{ name: 'e' },
{ name: 'f' },
{ name: 'g' },
{ name: 'h' },
{ name: 'i' },
{ name: 'j' },
{ name: 'k' },
{ name: 'l' },
];
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '100%',
backgroundColor: '#CED0CE',
}}
/>
);
};
searchItems = text => {
const newData = this.arrayNew.filter(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
data: newData,
value: text,
});
};
renderHeader = () => {
return (
<TextInput
style={{ height: 60, borderColor: '#000', borderWidth: 1 }}
placeholder=" Type Here...Key word"
onChangeText={text => this.searchItems(text)}
value={this.state.value}
/>
);
};
render() {
return (
<View
style={{
flex: 1,
padding: 25,
width: '98%',
alignSelf: 'center',
justifyContent: 'center',
}}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<Text style={{ padding: 10 }}>{item.name} </Text>
)}
keyExtractor={item => item.name}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
</View>
);
}
}
export default FlatListDropDown;
Feel free for doubts.

How to get data just access_token at react native rest api after login and show at cases

So, I want to display the access token obtained from the user when logging in from Cases.js ... But I have tried several ways to display it, but still not just the access_token ... But carried away with others ...
Maybe someone can help to solve this problem ..
thank you
The thing that I have tried is to retrieve the value of the existing token and access token, but still the appearance of all the data such as "access_token", "bearer", "scope", "refresh_token" ...
not only access_token ...
This is Form.js
import React, { Component } from 'react';
import { Text, View, StyleSheet, TextInput, TouchableOpacity, AsyncStorage, Animated, ImageBackground} from 'react-native';
import { Actions } from 'react-native-router-flux';
const ACCESS_TOKEN = 'access_token';
export default class Form extends Component {
constructor(){
super()
this.state ={
darikiri : new Animated.Value(0),
darikanan : new Animated.Value(0),
daribawah : new Animated.Value(0),
grant_type : "password",
scope : "",
client_id : "",
client_secret : "",
username : "",
password : "",
error : "",
}
}
async storeToken(accessToken){
try{
await AsyncStorage.setItem(ACCESS_TOKEN, accessToken);
this.getToken();
}catch (error){
console.log("something where wrong")
}
}
async getToken(){
try{
let token = await AsyncStorage.getItem(ACCESS_TOKEN);
console.log("token is : "+ token)
}catch (error){
console.log("something where wrong")
}
}
async removeToken(){
try {
let token = await AsyncStorage.removeItem(ACCESS_TOKEN);
this.getToken();
} catch(error){
console.log("Something went wrong")
}
}
_start = () => {
return Animated.parallel([
Animated.timing(this.state.darikiri, {
toValue: 1,
duration: 800,
useNativeDriver: true
}),
Animated.timing(this.state.darikanan, {
toValue: 1,
duration: 800,
useNativeDriver: true
}),
Animated.timing(this.state.daribawah, {
toValue: 1,
duration: 800,
useNativeDriver: true
})
]).start();
};
async onLoginPressed(){
try {
let response = await fetch('https://bpm.asihputera.or.id/asihputera/oauth2/token', {
method: 'POST',
headers: {
'Content-Type' : 'application/json',
'Accept-Encoding' : 'gzip, deflate',
'Authorization' : 'Bearer cde4e4bc600afcb604fb2ba078c60a16e29dac04',
'User-Agent' : 'PostmanRuntime/7.15.2',
'Accept' : '*/*',
'Cache-Control' : 'no-cache',
'Postman-Token' : 'ad9e715b-a2af-4f3f-86dd-11a7b6ec6037,f00ce420-e144-47ec-be83-756ec1fbc5d2',
'Host' : 'bpm.asihputera.or.id',
'Cookie' : 'PM-TabPrimary=101010010; singleSignOn=0',
'Content-Length' : '139',
'Connection' : 'keep-alive',
'cache-control' : 'no-cache',
},
body: JSON.stringify({
'grant_type' : "password",
'scope' : '*',
'client_id' : 'QKQYKIBJUXFRMGITBPKXVBWOVMFYPWWF',
'client_secret' : '2922119675d440616c9a613026663027',
'username' : this.state.username,
'password' : this.state.password,
}),
});
let res = await response.text();
if (response.status >= 200 && response.status <=300) {
this.setState({error:""});
let accessToken = res;
this.storeToken(accessToken);
let token = await AsyncStorage.getItem(ACCESS_TOKEN);
console.log("res token: "+accessToken);
Actions.Cases({"userName" :this.state.username ,"Password": this.state.password, "Token" : accessToken.access_token})
} else {
let error = res;
throw error;
}
} catch(error){
this.removeToken();
this.setState({error: error});
console.log("error" + error);
}
}
render(){
return(
<View onLayout={this._start} style={styles.container}>
<Animated.View
style={{
transform: [
{
translateX: this.state.darikiri.interpolate({
inputRange: [0, 1],
outputRange: [-900, 0]
})
}
],
}}
>
<TextInput style={styles.inputBox}
editable={true}
onChangeText = {(username)=> this.setState({username})}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Username"
ref='username'
returnKeyType='next'
value={this.state.username}
placeholderTextColor="#ffffff"
selectionColor="#fff"/>
</Animated.View>
<Animated.View
style={{
transform: [
{
translateX: this.state.darikanan.interpolate({
inputRange: [0, 1],
outputRange: [900, 0]
})
}
],
}}
>
<TextInput style={styles.inputBox}
editable={true}
onChangeText={(password) => this.setState({password})}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder='Password'
ref='password'
returnKeyType='next'
secureTextEntry={true}
value={this.state.password}
placeholderTextColor="#ffffff"
selectionColor="#fff"/>
</Animated.View>
<Animated.View
style={{
transform: [
{
translateY: this.state.daribawah.interpolate({
inputRange: [0, 1],
outputRange: [900, 0]
})
}
],
}}
>
<TouchableOpacity style={styles.button} onPress={this.onLoginPressed.bind(this)}>
<Text style={styles.buttonText}> Log In </Text>
</TouchableOpacity>
</Animated.View>
<Text>
{this.state.error}
</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container :{
flexGrow:1,
justifyContent:'center',
alignItems:'center',
},
inputBox: {
width: 300,
backgroundColor:'#C0C0C0',
borderRadius: 25,
paddingHorizontal: 16,
fontSize :14,
color: '#ffffff',
marginVertical: 13
},
buttonText: {
fontSize : 16,
fontWeight : '500',
color: '#ffffff',
textAlign:'center'
},
button: {
width:100,
backgroundColor: '#C0C0C0',
borderRadius: 40,
marginVertical: 30,
paddingVertical: 13
}
});
This is Cases.js
import React, {Component} from 'react';
import {Alert, Image, Text, TouchableOpacity, View, StyleSheet, ScrollView, AsyncStorage, Animated} from 'react-native';
import {Actions} from 'react-native-router-flux';
import {Fonts} from '../utils/Fonts';
import Wallpaper from '../components/Wallpaper';
const ACCESS_TOKEN = 'access_token';
export default class Cases extends Component {
async storeToken(accessToken){
try{
await AsyncStorage.setItem(ACCESS_TOKEN, accessToken);
this.getToken();
}catch (error){
console.log("something where wrong")
}
}
async getToken(){
try{
let token = await AsyncStorage.getItem(ACCESS_TOKEN);
console.log("token is : "+ token)
}catch (error){
console.log("something where wrong")
}
}
async removeToken(){
try {
let token = await AsyncStorage.removeItem(ACCESS_TOKEN);
this.getToken();
} catch(error){
console.log("Something went wrong")
}
}
constructor(props){
super(props)
this.state ={
accessToken : this.props.Token,
user : this.props.userName,
role : "",
ready : false,
ygdarikiri : new Animated.Value(0),
ygdarikanan : new Animated.Value(0),
}
}
userLogout() {
Actions.login();
}
/*async getRole(){
try {
let response = await fetch('https://bpm.asihputera.or.id/api/1.0/users/', {
method: 'GET',
headers: {
'Content-Type' : 'application/json',
'Accept-Encoding' : 'gzip, deflate',
'Authorization' : 'Bearer '+ this.state.accessToken,
},
body: JSON.stringify({
'grant_type' : "password",
'scope' : '*',
'client_id' : 'QKQYKIBJUXFRMGITBPKXVBWOVMFYPWWF',
'client_secret' : '2922119675d440616c9a613026663027',
'username' : this.state.username,
'password' : this.state.password,
}),
});
let res = await response.text();
if (response.status >= 200 && response.status <=300) {
this.setState({error:""});
let accessToken = res;
this.storeToken(accessToken);
this.getToken();
console.log("res token: "+accessToken);
Actions.Cases({"userName" :this.state.username ,"Password": this.state.password})
} else {
let error = res;
throw error;
}
} catch(error){
this.removeToken();
this.setState({error: error});
console.log("error" + error);
}
}
*/
_start = () => {
return Animated.parallel([
Animated.timing(this.state.ygdarikiri, {
toValue: 1,
duration: 800,
useNativeDriver: true
}),
Animated.timing(this.state.ygdarikanan, {
toValue: 1,
duration: 800,
useNativeDriver: true
})
]).start();
};
render() {
let {ygdarikanan, ygdarikiri} = this.state;
return (
<View style={styles.tampilan} onLayout={this._start}>
<View style ={{flexDirection:'row'}}>
<Text style={styles.textasih}>
ASIH PUTERA
</Text>
<TouchableOpacity style={styles.button} onPress={this.userLogout}>
<Text style={styles.buttonText}> Logout </Text>
</TouchableOpacity>
</View>
<View style={styles.garis} />
<Text style={styles.textwelcome}>Username : {this.state.user}</Text>
<Text style={styles.textwelcome}>Access_Token : {this.state.Token}</Text>
<View style={styles.garis} />
<ScrollView>
<View style={{flexDirection: 'row'}}>
<Animated.View
style={{
transform: [
{
translateX: ygdarikiri.interpolate({
inputRange: [0, 1],
outputRange: [-900, 0]
})
}
],
width: 180,
height: 180,
backgroundColor:'#bff5ff',
}}
>
<TouchableOpacity style={styles.touchCases}>
<Text style={styles.btnMenu}> CASES </Text>
</TouchableOpacity>
</Animated.View>
<Animated.View
style={{
transform: [
{
translateX: ygdarikanan.interpolate({
inputRange: [0, 1],
outputRange: [900, 0]
})
}
],
width: 180,
height: 180,
}}
>
<TouchableOpacity style={styles.touchInbox}>
<Text style={styles.btnMenu}> INBOX </Text>
</TouchableOpacity>
</Animated.View>
</View>
<View style={{flex: 1, flexDirection: 'row'}}>
<Animated.View
style={{
transform: [
{
translateX: ygdarikiri.interpolate({
inputRange: [0, 1],
outputRange: [-1800, 0]
})
}
],
width: 180,
height: 180,
backgroundColor:'#bff5ff',
}}
>
<TouchableOpacity style={styles.touchOutbox}>
<Text style={styles.btnMenu}> OUTBOX </Text>
</TouchableOpacity>
</Animated.View>
<Animated.View
style={{
transform: [
{
translateX: ygdarikanan.interpolate({
inputRange: [0, 1],
outputRange: [1800, 0]
})
}
],
width: 180,
height: 180,
backgroundColor:'#bff5ff',
}}
>
<TouchableOpacity style={styles.touchParticipated}>
<Text style={styles.btnMenu}> PARTICIPATED </Text>
</TouchableOpacity>
</Animated.View>
</View>
<View style={{flex: 1, flexDirection: 'row'}}>
<Animated.View
style={{
transform: [
{
translateX: ygdarikiri.interpolate({
inputRange: [0, 1],
outputRange: [-2700, 0]
})
}
],
width: 180,
height: 180,
backgroundColor:'#bff5ff',
}}
>
<TouchableOpacity style={styles.touchUnassigned}>
<Text style={styles.btnMenu}> UNASSIGNED </Text>
</TouchableOpacity>
</Animated.View>
<Animated.View
style={{
transform: [
{
translateX: ygdarikanan.interpolate({
inputRange: [0, 1],
outputRange: [2700, 0]
})
}
],
width: 180,
height: 180,
backgroundColor:'#bff5ff',
}}
>
<TouchableOpacity style={styles.touchPaused}>
<Text style={styles.btnMenu}> PAUSED </Text>
</TouchableOpacity>
</Animated.View>
</View>
</ScrollView>
<Text style={styles.textcpyr}>{'\u00A9'} ASIH PUTERA</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container :{
flexGrow:1,
justifyContent:'center',
alignItems:'center',
},
btnMenu:{
textAlign: 'center',
paddingTop: 70,
fontFamily: Fonts.LexendExa,
fontSize : 20,
fontWeight: "bold",
},
touchCases:{
width: 180,
height: 180,
backgroundColor:'#bff5ff',
},
touchInbox:{
width: 180,
height: 180,
backgroundColor:'#6bffc2',
},
touchOutbox:{
width: 180,
height: 180,
backgroundColor:'#83c3ff',
},
touchParticipated:{
width: 180,
height: 180,
backgroundColor:'#70ff8a',
},
touchUnassigned:{
width: 180,
height: 180,
backgroundColor:'#ffdeaa',
},
touchPaused:{
width: 180,
height: 180,
backgroundColor:'#dd8aff',
},
inputBox: {
width: 300,
backgroundColor:'#C0C0C0',
borderRadius: 25,
paddingHorizontal: 16,
fontSize :14,
color: '#ffffff',
marginVertical: 13
},
textwelcome:{
marginHorizontal: 15,
fontFamily: Fonts.LexendExa,
fontSize: 15,
},
textcpyr:{
paddingBottom:15,
textAlign: "center",
fontFamily: Fonts.LexendExa,
fontSize: 15
},
buttonText: {
fontSize : 16,
fontWeight : '500',
color: '#FFFFFF',
textAlign:'center'
},
button: {
width:100,
backgroundColor: '#C0C0C0',
borderRadius: 40,
marginVertical: 5,
marginHorizontal: 100,
paddingVertical: 13,
},
textasih:{
marginVertical:20,
marginHorizontal: 15,
fontFamily: Fonts.LexendExa,
fontSize: 15
},
tampilan :{
backgroundColor: '#cfe6f4',
flex:1
},
garis:{
width: 360,
height: 2,
backgroundColor: 'gray',
marginVertical: 1
},
});
And then, this is a Login.js
import React, { Component } from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity,Animated,ScrollView } from 'react-native';
import Logo from '../components/Logo';
import Form from '../components/Form';
import {Actions} from 'react-native-router-flux';
import Wallpaper from '../components/Wallpaper';
export default class Login extends Component {
render() {
return(
<View style={styles.container}>
<Wallpaper>
<Logo navigation = {this.props.navigation}/>
<Form navigation = {this.props.navigation} type ="Login"/>
</Wallpaper>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
backgroundColor : '#FFFFE0',
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
signupTextCont: {
flexGrow: 1,
alignItems: 'center',
justifyContent: 'flex-end',
paddingVertical: 16,
flexDirection: 'row'
},
signupText:{
color: 'rgba(255,255,255, 0.7)',
fontSize: 16,
paddingVertical: 30,
marginVertical: 30
},
signupButton: {
color: '#ffffff',
fontSize: 16,
fontWeight:'500'
}
});
This is the example the text of all value accessToken :
res token :
{"access_token":"//value of access_token","expires_in":"86400","token_type":"bearer","scope":"*","refresh_token":"//value of refresh_token"}
token is :
{"access_token":"//value of access_token","expires_in":"86400","token_type":"bearer","scope":"*","refresh_token":"//value of refresh_token"}
I hope i get a solution at here :D thank you
You can get the JSON result of your REST request and then access the 'access_token' member, like this:
try {
let response = await fetch('https://bpm.asihputera.or.id/api/1.0/users/', {
method: 'GET',
headers: {
'Content-Type' : 'application/json',
'Accept-Encoding' : 'gzip, deflate',
'Authorization' : 'Bearer '+ this.state.accessToken,
},
body: JSON.stringify({
'grant_type' : "password",
'scope' : '*',
'client_id' : 'QKQYKIBJUXFRMGITBPKXVBWOVMFYPWWF',
'client_secret' : '2922119675d440616c9a613026663027',
'username' : this.state.username,
'password' : this.state.password,
}),
});
let res = await response.json(); // this line
if (response.status >= 200 && response.status <=300) {
this.setState({error:""});
let accessToken = res;
this.storeToken(accessToken.access_token); //and this line
this.getToken();
console.log("res token: "+accessToken);
Actions.Cases({"userName" :this.state.username ,"Password": this.state.password})
} else {
let error = res;
throw error;
}
} catch(error){
this.removeToken();
this.setState({error: error});
console.log("error" + error);
}

React Native - Google Autocomplete API

My problem is the Text result of descriptions is overlapping to each other. I do not know if this a bug, I just can't make it solve it. I tried anything about the styles but nothing works. I need help from other with different perspective. Thank you for taking time to read this.
Image of the overlapping texts:
I also get a warning about the unique key prop, just adding this issue because it might be related to my problem.
Image of the Warning key prop:
Here are my codes:
async onChangeDestination(destination) {
this.setState({ destination });
const apiUrl = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${apiKey}
&input=${destination}&location=${this.state.focusedLocation.latitude},
${this.state.focusedLocation.longitude
}&radius=2000`;
try {
const result = await fetch(apiUrl);
const json = await result.json();
console.log(json);
this.setState({
predictions: json.predictions
});
} catch (err) {
console.log(err)
}
}
render() {
//For Prediction
const predictions = this.state.predictions.map(prediction => (
<View style={styles.descriptionContainer}>
<Text key={prediction.id} style={styles.descriptionText}>{prediction.description}</Text>
</View>
));
//For Marker
let marker = null;
if(this.state.locationChosen) {
marker = <MapView.Marker coordinate={this.state.markerPosition}/>
}
return(
<View style={styles.container}>
{/* <StatusBar backgroundColor={'transparent'} translucent={true}/> */}
<MapView
style={styles.map}
initialRegion={this.state.focusedLocation}
onPress={this.pickLocationHandler}
showsUserLocation={true}
ref={ref => this.map = ref} //For animating map movement
>
{marker}
</MapView>
{/* <TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
<Icon name="md-locate" size={30} color="blue"/>
</TouchableOpacity> */}
<TextInput
placeholder="Search for an event or place!"
style={styles.destinationInput}
onChangeText={destination => {
this.setState({destination});
this.onChangeDestinationDebounced(destination)
}}
value={this.state.destination}
/>
{predictions}
</View>
);
}
const styles = StyleSheet.create({
container: {
zIndex: -1,
alignItems: 'center',
},
map: {
height: '100%',
width: '100%'
},
iconContainer: {
position: 'absolute',
top: 60,
right: 15,
zIndex: 1
},
destinationInput: {
position: 'absolute',
zIndex: 10,
width: '97%',
top: 15,
backgroundColor: 'white',
borderRadius: 8,
padding: 8
},
descriptionText: {
color: 'black',
position: 'absolute',
zIndex: 10,
top: 60,
},
descriptionContainer: {
zIndex: 2,
position: 'absolute',
top: 20,
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
justifyContent: 'space-between'
}
})
So I haven't been able to run the code, however your descriptionText style has position: 'absolute'. The behaviour you are seeing is therefor expected, as each text is placed on the same 'absolute' position. Removing this should give you the result you want.
The key warning is thrown as your descriptionContainer View is the root element in the map function, so this should have the key. Hopefully this helps, updated source code below with a small disclaimer that I wasn't able to test it.
async onChangeDestination(destination) {
this.setState({ destination });
const apiUrl = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${apiKey}
&input=${destination}&location=${this.state.focusedLocation.latitude},
${this.state.focusedLocation.longitude
}&radius=2000`;
try {
const result = await fetch(apiUrl);
const json = await result.json();
console.log(json);
this.setState({
predictions: json.predictions
});
} catch (err) {
console.log(err)
}
}
render() {
//For Prediction
const predictions = this.state.predictions.map(prediction => (
<Text key={prediction.id} style={styles.descriptionText}>{prediction.description}</Text>
));
//For Marker
let marker = null;
if(this.state.locationChosen) {
marker = <MapView.Marker coordinate={this.state.markerPosition}/>
}
return(
<View style={styles.container}>
{/* <StatusBar backgroundColor={'transparent'} translucent={true}/> */}
<MapView
style={styles.map}
initialRegion={this.state.focusedLocation}
onPress={this.pickLocationHandler}
showsUserLocation={true}
ref={ref => this.map = ref} //For animating map movement
>
{marker}
</MapView>
{/* <TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
<Icon name="md-locate" size={30} color="blue"/>
</TouchableOpacity> */}
<TextInput
placeholder="Search for an event or place!"
style={styles.destinationInput}
onChangeText={destination => {
this.setState({destination});
this.onChangeDestinationDebounced(destination)
}}
value={this.state.destination}
/>
{this.state.predictions && this.state.predictions.length > 0 && (
<View style={styles.descriptionContainer}>{predictions}</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
zIndex: -1,
alignItems: 'center',
},
map: {
height: '100%',
width: '100%'
},
iconContainer: {
position: 'absolute',
top: 60,
right: 15,
zIndex: 1
},
destinationInput: {
position: 'absolute',
zIndex: 10,
width: '97%',
top: 15,
backgroundColor: 'white',
borderRadius: 8,
padding: 8
},
descriptionText: {
color: 'black',
},
descriptionContainer: {
zIndex: 2,
position: 'absolute',
top: 20,
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
}
})

Get all the image shots from dibbbler API

I am trying to learn react-native, I just start working on this project two days ago.
I have kind of confusing in how to get the all the image shots from dibbbler API and display it on my android emulator.
This is what I have done,
'use strict';
import React, {
AppRegistry,
Component,
Image,
ListView,
StyleSheet,
View,
} from 'react-native';
var API_URL = 'https://api.dribbble.com/v1/shots';
class myproject extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(API_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.images.treaser),
loaded: true,
});
})
.done();
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.rendershots}
style={styles.listView}
/>
);
}
rendershots(shots) {
return (
<View style={styles.container}>
<Image
source={{uri: shots.images.treas}}
style={styles.images.treas}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
rightContainer: {
flex: 1,
},
treas: {
width: 53,
height: 81,
},
listView: {
paddingTop: 20,
backgroundColor: '#F5FCFF',
},
});
AppRegistry.registerComponent('myproject', () => myproject);
You need to provide credentials to retrieve the pictures from dribble.
You can register your app here to get credentials then use them to use the Dribbble API.

Eliminating extreme redundancies in User Onboarding Keyword Selection

In the code below, I am attempting to provide an onboarding component that enables the user to select out keywords they are interested in. In doing so, a function is triggered that changes the state of that keyword to true, and changes the color of the component to a color that indicates that that keyword is in fact selected.
The problem is that my current code is very redundant in naming these keywords as state (which are also in an array in the same code file). Is there anyway to do this dynamically, in which there is a state array of selected keywords rather than 30 states indicated by each keyword that change when pressed?
var React = require('react-native');
var {
View,
ScrollView,
Image,
StyleSheet,
Text,
TouchableHighlight,
} = React;
//additional libraries
var Parse = require('parse/react-native'); //parse for data storage
Icon = require('react-native-vector-icons/Ionicons'); //vector icons
var LinearGradient = require('react-native-linear-gradient'); //linear grad. over button
//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');
//dynamic variable components
var ImageButton = require('../common/imageButton');
var KeywordBox = require('./onboarding/keyword-box');
var ActionButton = require('../common/ActionButton');
module.exports = React.createClass({
getInitialState: function() {
return {
isFinished: false,
BlackLivesMatter: false,
Adventure_Travel: false,
Arts: false,
Auto: false,
Basketball: false,
Book_Reviews: false,
Business: false,
Celebrity_News: false,
Computers: false,
Design: false,
Entertainment: false,
Entrepreneurship: false,
Fashion_Trends: false,
Film: false,
Happiness: false,
Health: false,
Hip_Hop: false,
History: false,
Humor: false,
Internet: false,
LGBQT: false,
Management: false,
Marketing: false,
Mobile_Games: false,
Music: false,
News: false,
Performing_Arts: false,
Photography: false,
Politics: false,
Sports: false,
Technology: false,
Travel: false,
Trending: false,
Universe: false,
Women_of_Color: false,
World: false,
};
},
render: function() {
return (
<View style={[styles.container]}>
<Image
style={styles.bg}
source={require('./img/login_bg1_3x.png')}>
<View style={[styles.header, this.border('red')]}>
<View style={[styles.headerWrapper]} >
<Image
resizeMode={'contain'}
style={[styles.onboardMsg]}
source={require('./img/onboard_msg.png')} >
</Image>
</View>
</View>
<View style={[styles.footer, this.border('blue')]}>
<ScrollView
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal={false}
style={styles.footerWrapperNC}
contentContainerStyle={[styles.footerWrapper]}>
{this.renderKeywordBoxes()}
</ScrollView>
</View>
</Image>
<ActionButton
onPress={this.onNextPress}
buttonColor="rgba(0,0,0,0.7)" />
</View>
);
},
renderKeywordBoxes: function() {
//renders array of keywords in keyword.js
//and maps them onto custom component keywordbox to show in the onboarding
//component
var Keywords = ['LGBQT', 'BlackLivesMatter', 'Arts', 'Hip-Hop', 'History',
'Politics', 'Fashion Trends', 'Entrepreneurship', 'Technology', 'Business',
'World', 'Health', 'Trending', 'Music', 'Sports', 'Entertianment',
'Mobile Games', 'Design', 'News', 'Humor', 'Happiness', 'Women of Color', 'Travel',
'Photography','Computers', 'Universe', 'Internet','Performing Arts','Management',
'Celebrity News', 'Book Reviews', 'Marketing', 'Basketball', 'Film', 'Adventure Travel',
'Auto'];
return Keywords.map(function(keyword, i) {
return <KeywordBox
key={i} text={keyword}
onPress={ () => { this.onKeywordPress(keyword) }}
selected={this.state.+keyword}/>
});
},
onKeywordPress: function(keyword) {
//take the spaces out the word
keyword = keyword.split(' ').join('_');
keyword = keyword.split('-').join('_');
//change the state accordingly without doing so directly
let newState = {...this.state};
newState[keyword] = !newState[keyword];
this.setState(newState);
console.log(keyword, newState);
},
onNextPress: function() {
},
//function that helps with laying out flexbox itmes
//takes a color argument to construct border, this is an additional
//style because we dont want to mess up our real styling
border: function(color) {
return {
//borderColor: color,
//borderWidth: 4,
}
},
});
styles = StyleSheet.create({
header: {
flex: 2,
},
headerWrapper: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent:'space-around',
marginTop: window.height/35,
},
onboardMsg: {
width: (window.width/1.2),
height: (452/1287)*((window.width/1.2)),
},
footer: {
flex: 7,
marginTop: window.height/35,
marginLeft: window.width/30,
},
//container style wrapper for scrollview
footerWrapper: {
flexWrap: 'wrap',
alignItems: 'flex-start',
flexDirection:'row',
},
//non-container style wrapper for scrollview
footerWrapperNC: {
flexDirection:'column',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
bg: {
flex: 1,
width: window.width,
height: window.height,
},
});
which looks like this:
Determined answer in the following subset of code. Made a state array and updated a temp array that has the same boolean states as the state array to avoid direct manipulation (outside of setState):
var React = require('react-native');
var {
View,
ScrollView,
Image,
StyleSheet,
Text,
TouchableHighlight,
} = React;
//additional libraries
var Parse = require('parse/react-native'); //parse for data storage
Icon = require('react-native-vector-icons/Ionicons'); //vector icons
var LinearGradient = require('react-native-linear-gradient'); //linear grad. over button
//need react-addons-update to use immutability helpers*******
//dimensions
var Dimensions = require('Dimensions');
var window = Dimensions.get('window');
//dynamic variable components
var ImageButton = require('../common/imageButton');
var KeywordBox = require('./onboarding/keyword-box');
var ActionButton = require('../common/ActionButton');
module.exports = React.createClass({
getInitialState: function() {
return {
keywords_array: Array.apply(null, Array(37)).map(Boolean.prototype.valueOf,false)
};
},
render: function() {
var newData = this.state.keywords_array;
return (
<View style={[styles.container]}>
<Image
style={styles.bg}
source={require('./img/login_bg1_3x.png')}>
<View style={[styles.header, this.border('red')]}>
<View style={[styles.headerWrapper]} >
<Image
resizeMode={'contain'}
style={[styles.onboardMsg]}
source={require('./img/onboard_msg.png')} >
</Image>
</View>
</View>
<View style={[styles.footer, this.border('blue')]}>
<ScrollView
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal={false}
style={styles.footerWrapperNC}
contentContainerStyle={[styles.footerWrapper]}>
{this.renderKeywordBoxes(newData)}
</ScrollView>
</View>
</Image>
<ActionButton
onPress={this.onNextPress}
buttonColor="rgba(0,0,0,0.7)" />
</View>
);
},
renderKeywordBoxes: function(newData) {
//renders array of keywords in keyword.js
//and maps them onto custom component keywordbox to show in the onboarding
//component
var Keywords = ['LGBQT', 'BlackLivesMatter', 'Arts', 'Hip-Hop', 'History',
'Politics', 'Fashion Trends', 'Entrepreneurship', 'Technology', 'Business',
'World', 'Health', 'Trending', 'Music', 'Sports', 'Entertianment',
'Mobile Games', 'Design', 'News', 'Humor', 'Happiness', 'Women of Color', 'Travel',
'Photography','Computers', 'Universe', 'Internet','Performing Arts','Management',
'Celebrity News', 'Book Reviews', 'Marketing', 'Basketball', 'Film', 'Adventure Travel',
'Auto'];
var that = this;
return Keywords.map(function(keyword, i) {
return <KeywordBox
key={i}
text={keyword}
onPress={ () => { that.onKeywordPress(i, keyword, newData) }}
selected={newData[i]} />
});
},
onKeywordPress: function(i, keyword, newData) {
console.log(this.state.keywords_array);
console.log(keyword);
console.log(newData);
//change the state accordingly without doing so directly
var array = newData;
array[i] = true;
this.setState({
keywords_array: array
});
console.log(array);
console.log(this.state.keywords_array);
},
onNextPress: function() {
},
//function that helps with laying out flexbox itmes
//takes a color argument to construct border, this is an additional
//style because we dont want to mess up our real styling
border: function(color) {
return {
//borderColor: color,
//borderWidth: 4,
}
},
});
styles = StyleSheet.create({
header: {
flex: 2,
},
headerWrapper: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent:'space-around',
marginTop: window.height/35,
},
onboardMsg: {
width: (window.width/1.2),
height: (452/1287)*((window.width/1.2)),
},
footer: {
flex: 7,
marginTop: window.height/35,
marginLeft: window.width/30,
},
//container style wrapper for scrollview
footerWrapper: {
flexWrap: 'wrap',
alignItems: 'flex-start',
flexDirection:'row',
},
//non-container style wrapper for scrollview
footerWrapperNC: {
flexDirection:'column',
},
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
bg: {
flex: 1,
width: window.width,
height: window.height,
},
});
Making a state array and a temp array (Updated) that has the same boolean states as the state array to avoid direct manipulation (outside of setState).