inProgress-team / inProgress-team/react-native-meteor
Reactivity on Meteor.loginWithPassword vs Accounts.createUser
- Dominant language
- JavaScript
- Stars
- 688
- Forks
- 200
- PR merge metrics
- No merged PRs in 30d
Description
I am using react-navigation, along with version 1.0.3 of react-native-meteor, and it appears that Accounts.createUser doesn't reactively update the user object in the same way Meteor.loginWithPassword does.
I originally thought this was a react-native re-rendering issue with react-navigation, but after moving around the screens and structure of my components, along with testing for re-rendering via console.log statements everywhere in my code, I am thinking this is just different behavior found in this package (possibly related to behavior related to AsyncStorage? see [issue #19](https://github.com/inProgress-team/react-native-meteor/issues/19))
My code is roughly as follows:
user data container:
```
export const AppContainer = createContainer(() => {
return {
loggedIn: !!Meteor.user(),
authInProgress: Meteor.loggingIn(),
connected: Meteor.status().connected,
};
}, App);
```
App:
```
export const App = ({ authInProgress, loggedIn, connected }) => {
const screenProps = {
loggedIn,
authInProgress,
};
return (
loggedIn ?
:
);
}
```
AuthStack:
```
export const AuthStack = StackNavigator({
Login: {
screen: Login,
},
Register: {
screen: Register,
},
}, {
headerMode: 'none',
});
```
Login:
```
export class Login extends Component {
static propTypes = {
screenProps: PropTypes.object,
navigation: PropTypes.object,
}
state = {
email: '',
emailError: '',
password: '',
passwordError: '',
authError: '',
}
resetErrors = () => {
this.setState({
emailError: '',
passwordError: ''
});
}
login = () => {
this.resetErrors();
let email = this.state.email.trim();
let password = this.state.password.trim();
// validate
isEmail(email) ? null : this.setState({emailError: 'Please provide a valid email'});
isValidPassword(password) ? null : this.setState({passwordError: 'Please provide a password longer than 6 characters'});
isNotEmpty(email) ? null : this.setState({emailError: 'Please provide an email'});
isNotEmpty(password) ? null : this.setState({passwordError: 'Please provide a password'});
if (isNotEmpty(email) && isNotEmpty(password) && isEmail(email) && isValidPassword(password)) {
// login
Meteor.loginWithPassword(email, password, (error) => {
if (error && error.reason === 'Incorrect password') {
this.setState({
passwordError: error.reason,
email,
});
} else if (error && error.reason === 'User not found') {
this.setState({
emailError: error.reason,
email,
});
} else if (error) {
this.setState({
authError: error.reason,
email,
});
}
});
}
}
handleEmailChange = (email) => this.setState({ email });
handlePasswordChange = (password) => this.setState({ password });
render() {
const { screenProps, navigation } = this.props;
if (screenProps.authInProgress) {
return ;
}
return (
Forgot Password?
navigation.navigate('Register')}
>Sign up
);
}
}
```
Register:
```
export class Register extends Component {
static propTypes = {
screenProps: PropTypes.object,
navigation: PropTypes.object,
}
state = {
email: '',
emailError: '',
password: '',
passwordError: '',
authError: '',
}
resetErrors = () => {
this.setState({
emailError: '',
passwordError: ''
});
}
register = () => {
this.resetErrors();
let email = this.state.email.trim();
let password = this.state.password.trim();
// validate
isEmail(email) ? null : this.setState({emailError: 'Please provide a valid email'});
isValidPassword(password) ? null : this.setState({passwordError: 'Please provide a password longer than 6 characters'});
isNotEmpty(email) ? null : this.setState({emailError: 'Please provide an email'});
isNotEmpty(password) ? null : this.setState({passwordError: 'Please provide a password'});
if (isNotEmpty(email) && isNotEmpty(password) && isEmail(email) && isValidPassword(password)) {
// Register
Accounts.createUser({
email,
password,
}, (error) => {
if (error) {
this.setState({
authError: error.reason,
email,
});
} else {
// hack to reactively login w/ react-native-meteor
Meteor.loginWithPassword(email, password, (error) => {
if (error) {
this.setState({
authError: error.reason,
email,
});
}
});
}
});
}
}
handleEmailChange = (email) => this.setState({ email });
handlePasswordChange = (password) => this.setState({ password });
render() {
const { screenProps, navigation } = this.props;
if (screenProps.authInProgress) {
return ;
}
return (
navigation.goBack()}
>Login
);
}
}
```
To work around this issue, you can see I called `Meteor.loginWithPassword()` on a successful `Accounts.createUser()` call, but I don't think things should really work this way.
I wanted to open this issue to see if there was a difference in how the two methods are implemented in this package that changes how `Meteor.user()` is reactively updated. Thanks!
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.