MartinDK81
MartinDK81

Reputation: 343

React and Firebase: return single item

I'm trying to return a single item from Firebase into my ReactJS app.

Why does this code not work?

renderItem: function() {
  var id = "-K7rCis1K3wyVnDbLzs3";
  var child = <h2>{this.state.items[id].title}</h2>
  return child;
},

In the console it says: Cannot read property 'title' of undefined

I can return a single item with all the data in it, but not just the title. What would the correct syntax be for this?

Thanks :)

* EDIT * Here's the complete code

var HelloWorld = React.createClass({
    mixins: [ReactFireMixin],
    getInitialState: function() {
      return {
        items: {},
        loaded: false
      };
    },
    componentWillMount: function() {
      fb = new Firebase("firebasepath");
      this.bindAsObject(fb, "items");
      fb.on("value", this.handleDataLoaded);
    },

    render: function() {
      return <div>
        {this.renderItem()}
      </div>
    },
    renderItem: function() {
      var id = "-K7rCis1K3wyVnDbLzs3";
      var child = <h2>{this.state.items[id].title}</h2>
      return child;
    },

    handleDataLoaded: function() {
      this.setState({loaded: true});
    }

  var element = React.createElement(HelloWorld);
  React.render(element, document.body);

Upvotes: 0

Views: 1208

Answers (2)

MartinDK81
MartinDK81

Reputation: 343

Thanks for the answer. I found a solution that fits into my code, here goes:

renderItem: function() {
      var id = "-K7rCis1K3wyVnDbLzs3";
      var item = this.state.items[id];
      if(item) {
        return <h2>{item.title}</h2>
      } else {
        <div>Loading..</div>
      }
    },

The reason why it wasn't showing, is that my component is rendering once before the data has actually loaded.

Upvotes: 0

Yura Zatsepin
Yura Zatsepin

Reputation: 736

To keep this.state.items in sync with any changes to the items node, make the following change in componentWillMount():

componentWillMount: function() {
   var ref = new Firebase("https://ReactFireTodoApp.firebaseio.com/items");
   this.bindAsArray(ref, "items");
}

Two key things in previous code:

1) ref is the link to "items" node: https://yourawesomeapp.firebaseio.com/items

You also can use ref to root node, but don't forget to get "items" ref as the child of root node:

ref = this.firebaseRef.child('items');

2) We bind items as array, not as object (it gives us more listeners like child_added, child_changed on items)

Also, you can get your item use this:

var ref = new Firebase("https://ReactFireTodoApp.firebaseio.com/items");
ref.child(key);

And the last thing, but also valued. Items is an array. And you can get the object from any array by index from 0 to array.length. But you have tried to get the element from the array by '.key'.

for (var i = 0; i < this.state.items.length; i++) {
    if (this.state.items[i]['.key'] === '-Kw3-fxa+0G42_w33Jf0') {
        console.log(this.state.items[i]);
    }
}

Upvotes: 1

Related Questions