Prince Hamza
Prince Hamza

Reputation: 1748

How to use SetState or function with firebase

this is my code from a React Project with firebase , I am stuck from the Morning in this Problem please help me plzzz

constructor (){
        super()
        this.state = {Message : false}
        this.Navigate = this.Navigate.bind(this)


        CompLoad = true

        var i = firebase.auth().currentUser.uid

        firebase.database().ref('users/' + i + '/inbox').limitToLast(1)

         .on('value' , function (x){

            if (CompLoad === false){

            var data = x.val()  

            alert(JSON.stringify(data))

            R = 'Inbox'

            this.Navigate()

            }

            if (CompLoad === true){
                CompLoad = false
            }


            })

            }

it gives me error :-

TypeError: Cannot read property 'Navigate' of null

Navigate function

Navigate =  () => {     
        this.context.router.history.push('/' + R)
    }

if i replace Navigate with setState

this.setState({
                Message : true
            })

react says :

TypeError: Cannot read property 'setState' of null

Upvotes: 0

Views: 388

Answers (4)

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

First of all, you should assign the property not variable inside the constructor:

Example:

CompLoad = true // incorrect
this.CompLoad = true // correct

Secondly, you should not use setState inside the constructor.

Thirdly, to access parent context this inside your function, you may use bind or use arrow function.

And finally, what you want to perform an api action and set the state, then, you should use componentDidMount lifecycle method and call api from there and update the state as necessary.

Upvotes: 0

Manoz
Manoz

Reputation: 6587

You should change this callback to use lexcial scope

.on('value' , function (x){
...

to

.on('value' , (x) => {
...

see more on lexical scoping

Upvotes: 1

Sagiv b.g
Sagiv b.g

Reputation: 31024

Your callback function is changing the context of this and its no longer the class.
Either use an arrow function to get a lexical context:

 .on('value' , (x) => {
....

Or temporarily hold the this value above the callback and use it:

// outside the callback in the constructor
const that = this;
// inside the callback
 .on('value' , function (x){
that.Navigate()

Upvotes: 2

Hemadri Dasari
Hemadri Dasari

Reputation: 33984

this isn’t accessible unitl and unless you bind it or use arrow function.

Change it to arrow function

    firebase.database().ref('users/' + i + '/inbox').limitToLast(1)

     .on('value' , (x) => {

        if (CompLoad === false){

        var data = x.val()  

        alert(JSON.stringify(data))

        R = 'Inbox'

        this.Navigate()

        }

        if (CompLoad === true){
            CompLoad = false
        }


        })

        }

Or bind it like

  firebase.database().ref('users/' + i + '/inbox').limitToLast(1)

     .on('value' , function (x){

        if (CompLoad === false){

        var data = x.val()  

        alert(JSON.stringify(data))

        R = 'Inbox'

        this.Navigate()

        }

        if (CompLoad === true){
            CompLoad = false
        }


        }.bind(this));

        }

Upvotes: 1

Related Questions