1

I am using React Native to build an app that relies on MongoDB Stitch for authentication. More often than not, the app crashes because the client object has not yet loaded when I use it in the following line of code. The error I get is the infamous TypeError: undefined is not an object followed by evaluating 'client.auth.user'.

import React from 'react';
import { View, Text } from 'react-native';
import { Stitch } from 'mongodb-stitch-react-native-sdk';

const APP_ID = '<my app ID>';

const client = Stitch.hasAppClient(APP_ID)
    ? Stitch.getAppClient(APP_ID)
    : Stitch.initializeDefaultAppClient(APP_ID);

const { user } = client.auth;

const Home = () => {
    return (
        <View style={styles.home}>
            <Text>HOME</Text>
            <Text>Hi {user.profile.data.email}</Text>
        </View>
    );
};

export default Home;

const styles = {
    home: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center'
    }
};

The example provided with the MongoDB Stitch NPM package uses componentDidMount (see here), but I am trying to make this work using Hooks. I have tried useEffect, a bunch of if statements, async/await, placing the object in state with useState; No luck.

halfer
  • 19,824
  • 17
  • 99
  • 186
thePicker
  • 11
  • 2
  • Can I see the mongoDB example ? – Bora Sumer Jan 14 '20 at 04:10
  • Thanks for your reply! Sure, here's the sample code provided with the package (using componentDidMount): https://www.npmjs.com/package/mongodb-stitch-react-native-sdk#getting-started – thePicker Jan 14 '20 at 19:14

1 Answers1

0

So yeah, you can use useEffect hook to instantiate the client and get the user info.

  useEffect(() => {
    _loadClient();
   }, []);

const [client,setClient] = useState({});
const [user,setUser] = useState({});

_loadClient() {
Stitch.initializeDefaultAppClient('<your-client-app-id>').then(client => {
 setClient(client);

  if(client.auth.isLoggedIn) {
    setUser( client.auth.user)
  }
});

}

That should do it.

Bora Sumer
  • 788
  • 6
  • 17
  • Thanks for the response! I tried using this code, and it works by itself, but as soon as I attempt to use the client from state (i.e. const { user } = client.auth) I still get the usual error. I think useEffect allows an initial render to happen before executing its function (_loadClient() in this case), and that causes the error. I wish I could have the entire component wait until _loadClient is done before doing anything else. – thePicker Jan 16 '20 at 01:42
  • You should be able to check if the client is loaded and render something else instead. Like, `Hi, {user ? user.profile.data.email : 'stranger' `. Maybe even use the `?.`-conditional access operator. And I guess this is what the new experimental react suspense thing is all about? https://reactjs.org/docs/concurrent-mode-suspense.html – Vegar May 12 '20 at 11:19