1

I currently initialize my state like this:

getInitialState: function () {
    return {
        conversations: {},
        messages: {},
        availableConversations: {}
    }
},

If I do something like:

convosRef.on('value', snapshot => {
        this.setState({ conversations: snapshot.val() });
    });

It works as desired... however:

users: {
    uid: {
        conversations: {
            conversationid: true,
            conversationid2: true
        }
    }
}

I successfully get the desired object:

userSnapshot.child('conversations').forEach(function (conversationKey) {
            var conversationRef = database.ref('conversations').child(conversationKey.key);
            conversationRef.on('value', function (conversationsSnapshot) {
                var conversation = conversationsSnapshot.val();
                conversationLoadedCount = conversationLoadedCount + 1;
                myObject[conversationKey.key] = conversation;
                // console.log(conversationKey.key);
                //this.state.conversations = conversation;

                if (conversationLoadedCount === conversationCount) {
                    console.log("We've loaded all conversations");

                }
            });
            this.setState({ conversations: myObject });
        });
    });

However. I receive two errors and I can't affect the state: First error: `FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot read property 'setState' of null``

And slightly similar: Uncaught TypeError: Cannot read property 'setState' of null

I based my code on this excellent answer with no success whatsoever: Firebase two-way relationships / Retrieving data

This is running inside the componentDidMount function.

Any suggestions on how to affect the state?

Community
  • 1
  • 1
villancikos
  • 519
  • 1
  • 6
  • 13
  • I found the solution to my problem. Just adding ".bind(this)" after each firebase call did the trick. I don't want to mark it as an answer because I could use some advice about performance :) – villancikos Feb 27 '17 at 12:08

2 Answers2

1

In ES6 if you use the fat arrow function this would be much cleaner and "this" would be bound, For example:

   userSnapshot.child('conversations').forEach((conversationKey) => {
            var conversationRef = database.ref('conversations').child(conversationKey.key);
            conversationRef.on('value', (conversationsSnapshot) => {
Jay Ordway
  • 1,708
  • 2
  • 11
  • 33
0

I found the solution to my problem just by trying to bind it. The solution is to use bind(this) whenever I do a call on the firebase.database().ref(). Here is the final snippet, hope it helps a poor soul like me and if someone has a better answer or some explanation on how to improve this please let me know:

var myObject = {}; usersRef.on('value', function (userSnapshot) {

        // First we get the qty of conversations.
        var conversationCount = userSnapshot.child('conversations').numChildren();
        // we initialize an empty counter
        var conversationLoadedCount = 0;
        // we traverse now the conversations ref with the past conversations.
        userSnapshot.child('conversations').forEach(function (conversationKey) {
            var conversationRef = database.ref('conversations').child(conversationKey.key);
            conversationRef.on('value', function (conversationsSnapshot) {
                var conversation = conversationsSnapshot.val();

                conversationLoadedCount = conversationLoadedCount + 1;
                myObject[conversationKey.key] = conversation;
                // console.log(conversationKey.key);
                this.state.conversations[conversationKey.key] = conversation;
                this.setState({ conversations: this.state.conversations });
                if (conversationLoadedCount === conversationCount) {
                    console.log("We've loaded all conversations");
                }
            }.bind(this)); // one for the usersRef
        }.bind(this)); // another one for the forEach inside 
    }.bind(this)); // the final one for the conversationRef.on...
villancikos
  • 519
  • 1
  • 6
  • 13