Aly Dabbous
Aly Dabbous

Reputation: 567

Unable to pass params successfully to another .js file/screen

I'm trying to pass params from one screen to another screen using react-navigation, the problem I'm encountering is that when I console.log the param itself, the console returns 'undefined'. I can't seem to pinpoint what I'm doing wrong exactly. Any help or guidance would be much appreciated.

I tried the following, with no success:

-this.props.navigation.getParam('biometryStatus') -this.props.navigation.state.params('biometryStatus')

This is my AuthenticationEnroll screen where my param is being initialised as the state of the component:

  export default class AuthenticationEnroll extends Component {
    constructor() {
        super()

        this.state = {
          biometryType: null
        };
    }

    async _clickHandler() {
        if (TouchID.isSupported()){
            console.log('TouchID is supported');
            return TouchID.authenticate()
            .then(success => {
                AlertIOS.alert('Authenticated Successfuly');
                this.setState({biometryType: true })
                this.props.navigation.navigate('OnboardingLast', {
                  pin: this.props.pin,
                  biometryStatus: this.state.biometryType,
                });
            })
            .catch(error => {
                console.log(error)
                AlertIOS.alert(error.message);
            });
        } else {
            this.setState({biometryType: false });
            console.log('TouchID is not supported');
            // AlertIOS.alert('TouchID is not supported in this device');
        }
    }

    _navigateOnboardingLast() {
      this.props.navigation.navigate('OnboardingLast', {pin: this.props.pin})
    }

    render () {
      return (
        <View style={{flex: 1}}>
          <Slide
            icon='fingerprint'
            headline='Secure authentication'
            subhead='To make sure you are the one using this app we use authentication using your fingerprints.'
            buttonIcon='arrow-right'
            buttonText='ENROLL'
            buttonAction={() => this._clickHandler()}
            linkText={'Skip for now.'}
            linkAction={() => this._navigateOnboardingLast()}
            slideMaxCount={4}
            slideCount={2}
            subWidth={{width: 220}}
          />
        </View>
      )
    }
} 

And this is my OnboardingLast Screen where my param is being passed down and printed through console.log:


class OnboardingLast extends Component {

  async _createTokenAndGo () {
    let apiClient = await this._createToken(this.props.pin)
    this.props.setClient(apiClient)
    AsyncStorage.setItem('openInApp', 'true')
    const { navigation } = this.props; 
    const biometryStatus = navigation.getParam('biometryStatus', this.props.biometryStatus);
    console.log(biometryStatus); 
    resetRouteTo(this.props.navigation, 'Home')
  }

  /**
  * Gets a new token from the server and saves it locally
  */
  async _createToken (pin) {
    const tempApi = new ApiClient()
    let token = await tempApi.createToken(pin)
    console.log('saving token: ' + token)
    AsyncStorage.setItem('apiToken', token)
    return new ApiClient(token, this.props.navigation)
  }

  render () {
    return (
      <View style={{flex: 1}}>
        <Slide
          icon='checkbox-marked-circle-outline'
          headline={'You\'re all set up!'}
          subhead='Feel free to start using MyUros.'
          buttonIcon='arrow-right'
          buttonText='BEGIN'
          buttonAction={() => this._createTokenAndGo()}
          slideMaxCount={4}
          slideCount={3}
        />
      </View>
    )
  }
} 

Expected Result is that console.log(biometryStatus); returns 'true' or 'false', however it returns 'undefined'.

Upvotes: 0

Views: 55

Answers (1)

Poptocrack
Poptocrack

Reputation: 3009

Since setState is asynchron, you send null (declared in your constructor) to your next page. By doing so, you will send true:

this.setState({ biometryType: true })
this.props.navigation.navigate('OnboardingLast', {
    pin: this.props.pin,
    biometryStatus: true,
});

You could also do this, since setState can take a callback as param:

this.setState({ biometryType: true }, () => {
  this.props.navigation.navigate('OnboardingLast', {
    pin: this.props.pin,
    biometryStatus: true,
  });
})

In your second page this.props.biometryStatus is undefined. The second argument of getParam is the default value. You should change it like that

const biometryStatus = navigation.getParam('biometryStatus', false);

Upvotes: 1

Related Questions