How to Navigate to Screen after GPS been enabled? - react-native

When the User is enabled the GPS I want to navigate it to AuthScreen.js. I'm using react-native-navigation v1 but there is no feature that can navigate just to simple screen, only push and modal but I don't want to use it.
Also using this: react-native-android-location-services-dialog-box
Here are my codes:
componentDidMount() {
this.gpsLocation();
}
gpsLocation = () => {
if (Platform.OS === 'android') {
LocationServicesDialogBox.checkLocationServicesIsEnabled({
message: "<h2>Use Location?</h2> \
This app wants to change your device settings:<br/><br/>\
Use GPS for location<br/><br/>",
ok: "Yes",
cancel: "No",
style: {
backgroundColor: '#4f6d7a',
positiveButtonTextColor: '#000000',
negativeButtonTextColor: '#000000'
},
enableHighAccuracy: true,
showDialog: true,
openLocationServices: true,
preventOutSideTouch: true,
preventBackClick: true,
providerListener: true
}).then(function(success) {
console.log(success)
// return <AuthScreen/>
}).catch((error) => {
console.log(error.message);
});
};
DeviceEventEmitter.addListener('locationProviderStatusChange', function(status) {
console.log(status);
});
};
componentWillUnmount() {
LocationServicesDialogBox.stopListener();
};
render() {
if(!this.state.nextScreen) {
return (
<View style={styles.container}>
</View>
);
} else {
return <AuthScreen/>
}
};

If you really don't want to navigate, you can use the .then() callback in which you're already logging the success parameter. According to the doc, success is an object with the following structure:
{
alreadyEnabled: false,
enabled: true,
status: "enabled"
}
You just need to check if success.enabled is true and if that's the case call setState({ nextScreen : true });
Edit: Here's the code, as requested:
// MyView.js
componentDidMount()
{
this.checkOrRequestLocationPermission();
}
checkOrRequestLocationPermission()
{
if (Platform.OS === 'android')
{
LocationServicesDialogBox.checkLocationServicesIsEnabled({
// Your config
// ...
})
.then(result => {
if (result.enabled)
{
this.setState({
nextScreen : true
});
}
// The above could be replaced by this
// this.setState({
// nextScreen : result.enabled
// });
})
.catch(error => {
console.warn('Error requesting location permission ' + error);
});
}
}
render() {
if(!this.state.nextScreen) {
return (
<View style={styles.container} />
);
}
else {
return <AuthScreen/>
}
};

Related

React-native: How to change the audio speed in expo-av

I'm having trouble changing the prop: 'rate' to change the speed of the audio being played.
I'm using expo-av (https://docs.expo.dev/versions/latest/sdk/av/).
Here's my code:
import {Text, View, Alert } from 'react-native'
import * as MediaLibrary from 'expo-media-library';
import { DataProvider } from 'recyclerlistview';
import {Audio} from 'expo-av';
import { play, pause, resume, playNext } from "../misc/AudioController";
export const AudioContext = createContext()
export class AudioProvider extends Component {
constructor(props) {
super(props);
this.state = {
audioFiles: [],
permissionError: false,
dataProvider: new DataProvider((r1, r2) => r1 !== r2),
playbackObj: null,
soundObj: null,
currentAudio: {},
isPlaying: false,
currentAudioIndex: null,
playbackPosition: null,
playbackDuration: null,
rate: 2.0,
};
this.totalAudioCount = 0;
}
permissionAlert = () => {
Alert.alert("Permission Required", "This app needs to read audio files", [
{ text: "I am ready", onPress: () => this.getPermission() },
{
text: "cancel",
onPress: () => this.permissionAlert(),
},
]);
};
getAudioFiles = async () => {
const { dataProvider, audioFiles } = this.state;
let media = await MediaLibrary.getAssetsAsync({
mediaType: "audio",
});
media = await MediaLibrary.getAssetsAsync({
mediaType: "audio",
first: media.totalCount,
});
this.totalAudioCount = media.totalCount;
this.setState({
...this.state,
dataProvider: dataProvider.cloneWithRows([
...audioFiles,
...media.assets,
]),
audioFiles: [...audioFiles, ...media.assets],
});
};
loadPreviousAudio = async () => {
let previousAudio = await AsyncStorageLib.getItem("previousAudio");
let currentAudio;
let currentAudioIndex;
if (previousAudio === null) {
currentAudio = this.state.audioFiles[0];
currentAudioIndex = 0;
} else {
previousAudio = JSON.parse(previousAudio);
currentAudio = previousAudio.audio;
currentAudioIndex = previousAudio.index;
}
this.setState({ ...this.state, currentAudio, currentAudio });
};
getPermission = async () => {
// {
// "canAskAgain": true,
// "expires": "never",
// "granted": false,
// "status": "undetermined",
// }
const permission = await MediaLibrary.getPermissionsAsync();
if (permission.granted) {
this.getAudioFiles();
}
if (!permission.canAskAgain && !permission.granted) {
this.setState({ ...this.state, permissionError: true });
}
if (!permission.granted && permission.canAskAgain) {
const { status, canAskAgain } =
await MediaLibrary.requestPermissionsAsync();
if (status === "denied" && canAskAgain) {
this.permissionAlert();
}
if (status === "granted") {
this.getAudioFiles();
}
if (status === "denied" && !canAskAgain) {
this.setState({ ...this.state, permissionError: true });
}
}
};
onPlaybackStatusUpdate = async (playbackStatus) => {
console.log("hier");
if (playbackStatus.isLoaded && playbackStatus.isPlaying) {
this.updateState(this, {
playbackPosition: playbackStatus.positionMillis,
playbackDuration: playbackStatus.durationMillis,
});
}
if (playbackStatus.didJustFinish) {
const nextAudioIndex = this.state.currentAudioIndex + 1;
if (nextAudioIndex >= this.totalAudioCount) {
this.state.playbackObj.unloadAsync();
this.updateState(this, {
soundObj: null,
currentAudio: this.state.audioFiles[0],
isPlaying: false,
currentAudioIndex: 0,
playbackPosition: null,
playbackDuration: null,
});
}
const audio = this.state.audioFiles[nextAudioIndex];
const status = await playNext(this.state.playbackObj, audio.uri);
this.updateState(this, {
soundObj: status,
currentAudio: audio,
isPlaying: true,
currentAudioIndex: nextAudioIndex,
});
}
};
componentDidMount() {
this.getPermission();
if (this.state.playbackObj === null) {
this.setState({ ...this.state, playbackObj: new Audio.Sound(), });
}
}
updateState = (prevState, newState = {}) => {
this.setState({ ...prevState, ...newState });
};
render() {
const {
audioFiles,
dataProvider,
permissionError,
playbackObj,
soundObj,
currentAudio,
isPlaying,
currentAudioIndex,
playbackPosition,
playbackDuration,
rate,
} = this.state;
if (permissionError)
return (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Text>It looks like you haven't accepted the permission</Text>
</View>
);
return (
<AudioContext.Provider
value={{
audioFiles,
dataProvider,
playbackObj,
soundObj,
currentAudio,
isPlaying,
currentAudioIndex,
totalAudioCount: this.totalAudioCount,
playbackPosition,
playbackDuration,
rate,
updateState: this.updateState,
loadPreviousAudio: this.loadPreviousAudio,
onPlaybackStatusUpdate: this.onPlaybackStatusUpdate
}}
>
{this.props.children}
</AudioContext.Provider>
);
}
}
import {Component} from 'react';
import AsyncStorageLib from '#react-native-async-storage/async-storage';
export default AudioProvider;
and here's some more:
// play audio
// Import the react-native-sound module
import { PitchCorrectionQuality,shouldCorrectPitch, rate } from "expo-av/build/AV.types";
export const play = async (playbackObj, uri,) => {
try {
return await playbackObj.loadAsync(
{uri},
{shouldPlay: true},
);
} catch (error) {
console.log('error inside play helper method', error.message)
}
};
//pause
export const pause = async playbackObj => {
try {
// playbackObj.setRateAsync(rate = 2.0, shouldCorrectPitch = true, PitchCorrectionQuality= High);
return await playbackObj.setStatusAsync({
shouldPlay: false},
);
} catch (error) {
console.log('error inside pause helper method', error.message)
}
};
//resume
export const resume = async playbackObj => {
try {
return await playbackObj.playAsync(
);
} catch (error) {
console.log('error inside pause resume method', error.message)
}
};
//select next
export const playNext = async (playbackObj, uri) => {
try {
await playbackObj.stopAsync()
await playbackObj.unloadAsync();
return await play(playbackObj, uri);
} catch (error) {
console.log('error inside playNext helper method')
}
}
I've tried including 'rate: 2.0' inside this.state{audioFiles: [],
permissionError: false, etc.} but it didn't work.
Also I've tried doing: await playbackObj.setRateAsync() in the 2nd code snippet.
Any suggestions?
Nvm, I found the solution. Here's my updated code:
// play audio
// Import the react-native-sound module
import { PitchCorrectionQuality,shouldCorrectPitch, rate } from "expo-av/build/AV.types";
export const play = async (playbackObj, uri,) => {
try {
await playbackObj.loadAsync(
{uri},
{shouldPlay: true},
);
return await playbackObj.setStatusAsync({ rate: 0.9749090909 });
} catch (error) {
console.log('error inside play helper method', error.message)
}
};
//pause
export const pause = async playbackObj => {
try {
return await playbackObj.setStatusAsync({
shouldPlay: false,
rate: 0.9749090909,
});
} catch (error) {
console.log('error inside pause helper method', error.message)
}
};
//resume
export const resume = async playbackObj => {
try {
return await playbackObj.playAsync(
);
} catch (error) {
console.log('error inside pause resume method', error.message)
}
};
//select next
export const playNext = async (playbackObj, uri) => {
try {
await playbackObj.stopAsync()
await playbackObj.unloadAsync();
return await play(playbackObj, uri);
} catch (error) {
console.log('error inside playNext helper method')
}
}

Why is InterstitialAd not loaded after the first trigger?

I manage to get the first ad to show, but app crashed the next time I try to trigger an ad. And gives me this error: Error: InterstitialAd.show() The requested InterstitialAd has not loaded and could not be shown
In App.js
componentDidMount() {
const eventListener = interstitial.onAdEvent(type => {
if (type === AdEventType.LOADED) {
this.setState({
setLoaded: true,
});
}
});
interstitial.load();
eventListener();
}
showAds = () => {
interstitial.show();
// No advert ready to show yet
if (!this.state.loaded) {
console.log('null');
return null;
}
};
// This trigger is within another function
this.showAds();
I have a class component so I use ComponentDidMount instead of useEffect. Might that cause some troubles?
UPDATE:
this.state = {
loaded: false,
setLoaded: false,
Listener: null,
};
The above state is an attempt to redo
const [loaded, setLoaded] = useState(false);
constructor () {
super();
this.Listener=null
}
componentDidMount() {
this.Listener = interstitial.onAdEvent(type => {
if (type === AdEventType.LOADED) {
this.setState({
loaded: true,
});
}else if(type === AdEventType.CLOSED){
this.loadAd()
}
});
this.loadAd()
}
componentWillUnmount(){
if(this.Listener!==null){
this.Listener()
}
}
loadAd = () =>{
this.setState({
loaded: false,
});
interstitial.load();
}
showAds = () => {
if (!this.state.loaded) {
console.log('null');
return null;
}else{
interstitial.show();
}
};

react native async getting data when running app first time

I have two components, in first components storing data in asyncstorage, in second component display data, when install app and save data does not get data from asyncstorage, when open app second time data are displayed.
storeData = async (item, messave, messrem) => {
const checkarary = this.state.favorite;
if(checkarary.some(e => e.name === item.name)) {
const value = this.state.favorite;
const position = value.filter((lists) => lists.id !== item.id);
this.setState({
favorite: position
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
Toast.show({
text: messrem,
buttonText: "Okay",
duration: 3000,
type: "danger"
});
});
} catch (error) {
}
});
} else {
this.setState({
favorite: [...this.state.favorite, item]
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
// AsyncStorage.getItem('favoriti', (err, result) => {
// console.log(result);
// });
Toast.show({
text: messave,
buttonText: "Okay",
duration: 3000,
type: "success"
});
});
} catch (error) {
}
});
}
};
Getting data in second component
_retrieveData = async () => {
try {
AsyncStorage.getItem('favoriti').then((value) => {
const parsed = JSON.parse(value);
this.setState({ favorite: parsed })
})
} catch (error) {
}
};
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
componentDidUpdate() {
this._retrieveData();
};
How fix this issue, is there some solution. Can I set Item and reload app when install app or somthing else.
Use this
componentWillMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
instead of
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
As componentWillMount is called after constructor is called for class and componentDidMount is called after screen is once rendered.

React Native - Cannot capture hardware back button click event

I used to react-native-navigation from the Wix for my app navigation. But it is not working properly. After authenticating the user by my application successfully navigate to the main screen, but the problem is when I pressed android back button it will navigate to the login screen again. I need to avoid that. How can I do it? Finally tried to completely exit from the application. But it also not working properly. I have tried a few solutions, but those solutions have not worked for me. Here I have attached few solutions that I have tried.
try 01 :
componentWillUnmount() {
if (Platform.OS === 'android') return
BackHandler.removeEventListener('hardwareBackPress')
}
componentWillMount() {
Alert.alert(
"Warning!",
"one")
if (Platform.OS === 'android' && this.props.login)
BackHandler.addEventListener('hardwareBackPress', () => {
Alert.alert(
"Warning!",
"two")
return true
})
}
try 01: this function working properly, but this isn't solving the problem.
try 02 :
constructor(props) {
super(props);
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
}
onNavigatorEvent(event) {
switch (event.id) {
case "willAppear":
this.backHandler = BackHandler.addEventListener(
"hardwareBackPress",
this.handleBackPress,
Alert.alert(
event.id,
"willAppear")
);
break;
case "willDisappear":
this.backPressed = 0;
Alert.alert(
"Warning!",
"willDisappear")
this.backHandler.remove();
break;
default:
break;
}
}
handleBackPress = () => {
console.log("handleBackPress");
if (this.backPressed && this.backPressed > 0) {
if (this.props.login) {
console.log("login");
RNExitApp.exitApp();
} else {
console.log("root");
this.props.navigator.popToRoot({ animated: false });
return false;
}
}
}
try 02: In this try "onNavigatorEvent (event)" working properly. But 1st time (1st time User login to the system, until the session saved) not working, but after that any time this function working.
This is the complete code.
LoginScreen.js
this.props.navigator.push({
screen: "auxxa.LandingScreen",
passProps: { login: true },
overrideBackPress: true,
navigatorStyle: {
navBarHidden: true
}
});
LandingScreen.js
constructor(props) {
super(props);
this.state = {
size: { width, height },
tileData: null,
isLoading: true,
user_id: null,
refetching: false,
access_token: null
};
// this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
}
onNavigatorEvent(event) {
switch (event.id) {
case "willAppear":
this.backHandler = BackHandler.addEventListener(
"hardwareBackPress",
this.handleBackPress,
Alert.alert(
event.id,
"willAppear")
);
break;
case "willDisappear":
this.backPressed = 0;
Alert.alert(
"Warning!",
"willDisappear")
this.backHandler.remove();
break;
default:
break;
}
}
handleBackPress = () => {
console.log("handleBackPress");
if (this.backPressed && this.backPressed > 0) {
if (this.props.login) {
console.log("login");
// RNExitApp.exitApp();
} else {
console.log("root");
this.props.navigator.popToRoot({ animated: false });
return false;
}
}
this.backPressed = 1;
this.props.navigator.showSnackbar({
text: "Press one more time to exit",
duration: "long"
});
return true;
};
componentWillUnmount() {
if (Platform.OS === 'android') return
BackHandler.removeEventListener('hardwareBackPress')
}
componentWillMount() {
Alert.alert(
"Warning!",
"one")
if (Platform.OS === 'android' && this.props.login)
BackHandler.addEventListener('hardwareBackPress', () => {
Alert.alert(
"Warning!",
"two")
return true
})
}
//Firebase initialization
componentDidMount() {
NetInfo.isConnected.addEventListener("change", this.handleConnectionChange);
// if network connected this will change the state --
NetInfo.isConnected.fetch().done(isConnected => {
if (isConnected) {
this.setState({ status: isConnected });
this._retrieveData();
}
else {
this.setState({ refetching: false })
// Alert.alert(
// "Warning!",
// "Please check your network connection.",
// [
// {
// text: "Cancel",
// onPress: () => console.log("Cancel Pressed"),
// style: "cancel"
// },
// { text: "OK", onPress: () => console.log("OK Pressed") }
// ],
// { cancelable: false }
// end here
// );
}
});
//Push Notification implementation
if (Platform.OS == "android") {
FCM.requestPermissions();
FCM.getFCMToken().then(token => {
console.log("TOKEN (getFCMToken)", token);
});
// This method get all notification from server side.
FCM.getInitialNotification().then(notif => {
console.log("INITIAL NOTIFICATION", notif);
});
// This method give received notifications to mobile to display.
this.notificationUnsubscribe = FCM.on(FCMEvent.Notification, notif => {
console.log("a", notif);
if (notif && notif.local_notification) {
return;
}
this.sendRemote(notif);
});
// this method call when FCM token is update(FCM token update any time so will get updated token from this method)
this.refreshUnsubscribe = FCM.on(FCMEvent.RefreshToken, token => {
console.log("TOKEN (refreshUnsubscribe)", token);
this.props.onChangeToken(token);
});
}
}
//Send Notifications method
sendRemote(notif) {
console.log("send");
FCM.presentLocalNotification({
title: notif.title,
body: notif.body,
priority: "high",
click_action: notif.click_action,
show_in_foreground: true
});
}
_retrieveData = async () => {
try {
const value = await AsyncStorage.multiGet(["id", "access_token"]);
if (value !== null) {
// We have data!!
console.log(value);
this.setState({ user_id: value[0][1] });
this.setState({ access_token: value[1][1] });
this.getLandingData();
}
} catch (error) {
// Error retrieving data
}
};
refetch = () => {
this.setState({ refetching: true })
this._retrieveData()
}
// if network state change then this method will check the isConnected true, if it is false
// this will popup the alert --
handleConnectionChange = isConnected => {
this.setState({ status: isConnected });
if (!isConnected) {
// alert dialog starting here --
Alert.alert(
"Warning!",
"Please check your network connection.",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "OK", onPress: () => console.log("OK Pressed") }
],
{ cancelable: false }
// end here
);
} else {
// this.getLandingData();
this.refetch();
}
};
// network conctivity check end here --
handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
async getLandingData() {
// let user_id = 18;
let url =
Config.BASE_URL +
`api/BIMobile/GetInitiatlTiles?userId=${encodeURIComponent(
this.state.user_id
)}`;
console.log(url);
fetch(url, {
method: "GET",
headers: {
Authorization: "Bearer " + this.state.access_token
},
})
.then(response => {
return response.json();
})
.then(responseData => {
//set your data here
console.log("responseData : ", responseData.messageCode);
if (responseData.data == null) {
Alert.alert(
"Oops! Something went wrong.",
"This page did not load correctly. Please contact helpdesk.",
[
{
text: "Cancel",
isLoading: true,
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "OK", isLoading: true, onPress: () => console.log("OK Pressed") }
],
{ cancelable: false }
// end here
);
} else {
if (responseData.messageCode.code == 1) {
this.setState({ tileData: responseData.data, isLoading: false });
} else if (responseData.messageCode.code == 0) {
console.log(responseData.messageCode.message)
}
}
})
.catch(error => {
console.error(error);
});
}
// this function set title to the page
module1Handler = (value, title) => {
this.props.navigator.push({
screen: value,
navigatorStyle: {
navBarHidden: false
},
title: title
});
};
_onLayoutDidChange = e => {
const layout = e.nativeEvent.layout;
this.setState({ size: { width: layout.width, height: layout.height } });
};
render() {
let menuItems = [];
console.log("title Data : " + this.state.tileData);
if (this.state.isLoading) {
// setup progressbar to the view --
// when the data is fetching this will spinning --
return <ActivityIndicator style={styles.activity_indicator_view} />;
} else {
return (
<View style={{ flex: 1 }} onLayout={this._onLayoutDidChange}>
<Swiper showsButtons={false} loop={false} showsPagination={false}>
{this.state.tileData.map((array, key) => {
if (key == 0) {
return (
<MainScreen
action={(value, title) => {
this.module1Handler(value, title);
}}
array={array}
/>
);
} else {
return (
<SliderScreen
action={(value, title) => {
this.module1Handler(value, title);
}}
array={array}
/>
);
}
})}
</Swiper>
</View>
);
}
}
}
const styles = StyleSheet.create({
activity_indicator_view: {
flex: 1,
flexDirection: "row",
height: "40%",
justifyContent: "space-around",
padding: 10
}
});
Appreciate if someone could assist me to correct way. Thanks.

React Native + Redux component renders before store action's complete

I have react native application with redux, where user get nevigated to home component after successful login. But home component get rendered before it receive user profile through store. If I use 'Home' component as connected component then on re-render it receives profile.
It is a correct flow or do I able to delay rendering of 'Home' till store is populated with new data.
Here is code
Types
export const FETCH_PROFILE = 'FETCH_PROFILE';
export const UPDATE_PROFILE = 'UPDATE_PROFILE';
export const DELETE_PROFILE = 'DELETE_PROFILE';
export const FETCH_STREAMS = 'FETCH_STREAMS';
Reducer
export default function profile(state = {}, action) {
switch (action.type) {
case types.FETCH_PROFILE:
return {
...state,
profile: action.profile
}
case types.UPDATE_PROFILE:
return {
...state,
profile: action.profile
}
case types.DELETE_PROFILE:
return {
...state,
profile: null
};
default:
return state;
}
}
Actions
var PROFILE_KEY = "#myApp:profile";
export function fetchProfile() {
return dispatch => {
AsyncStorage.getItem(PROFILE_KEY)
.then((profileString) => {
dispatch({
type: types.FETCH_PROFILE,
profile: profileString ? JSON.parse(profileString) : {}
})
})
}
}
export function updateProfile(data) {
return dispatch => {
AsyncStorage.setItem(PROFILE_KEY, JSON.stringify(data))
.then(() => {
dispatch({
type: types.UPDATE_PROFILE,
profile: data
})
})
}
}
export function deleteProfile() {
return dispatch => {
AsyncStorage.removeItem(PROFILE_KEY)
.then(() => {
dispatch({
type: types.DELETE_PROFILE
})
})
}
}
Login Component
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
username: "",
password: "",
error: "",
showProgress: false,
};
}
_focusNextField(nextField) {
this.refs[nextField].focus();
}
_onLoginPressed() {
this.setState({showProgress: true});
this._login();
}
async _login() {
try {
let response = await fetch( BASE_URL + url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
user: {
email: this.state.username,
password: this.state.password,
}
})
});
let res = await response.text();
if (response.status >= 200 && response.status < 300) {
let user = JSON.parse(res);
this.props.updateProfile(user.user);
this.setState({showProgress: false});
this.props.navigator.replace({name: 'Home'});
}
else {
let error = JSON.parse(res);
throw error.errors;
}
} catch(error) {
this.setState({error: error});
this.setState({showProgress: false});
console.log("error " + error);
}
}
render() {
return (
<View style={styles.loginBox}>
<TextInput
ref="username"
value={this.state.username}
placeholder="Username"
keyboardType="email-address"
onChangeText={(username) => this.setState({username}) }
onSubmitEditing={() => this._focusNextField('password')}/>
<TextInput
ref="password"
placeholder="Password"
value={this.state.password}
secureTextEntry={true}
onChangeText={(password) => this.setState({password}) }
returnKeyType="go"/>
<Button textStyle={{fontSize: 14}} onPress={this._onLoginPressed.bind(this)} style={{marginTop: 30}}>
Sign In
</Button>
</View>
);
}
}
const styles = StyleSheet.create({
loginBox: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
alignItems: 'stretch',
margin: 10,
}
});
var {updateProfile} = require('../Actions');
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
module.exports = connect(
null,
(dispatch) => {
return bindActionCreators({updateProfile}, dispatch)
}
)(Login)
Home
class Home extends React.Component {
render() {
return (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
<Text>Auth key : {this.props.profile ? this.props.profile.authentication_token : 'authentication_token'}</Text>
</View>
);
}
}
//module.exports = Home;
import { connect } from 'react-redux';
module.exports = connect(
(state) => {
return {
profile: state.profile
}
},
null
)(Home)
If you're using redux-thunk, you can delay the transition until data is loaded. You need to change some small things.
Add return to action creator.
export function updateProfile(data) {
return dispatch => {
return AsyncStorage.setItem(PROFILE_KEY, JSON.stringify(data))
.then(() => {
dispatch({
type: types.UPDATE_PROFILE,
profile: data
})
})
}
}
add await
if (response.status >= 200 && response.status < 300) {
let user = JSON.parse(res);
await this.props.updateProfile(user.user);
this.setState({showProgress: false});
this.props.navigator.replace({name: 'Home'});
}