1

I am new to both React and Firebase. I struggled a bit to get data from the database, even though the instructions on the Firebase website were pretty straightforward.

I managed to print data in the view by using this code:

Get data from DB and save it in state:

INSTRUMENTS_DB.once('value').then(function(snapshot) {
        this.state.instruments.push(snapshot.val());
        this.setState({
            instruments: this.state.instruments
        });

From Firebase, I receive and Object containing several objects, which correspond to the differen instruments, like shown in the following snippet:

Object {
    Object {
        name: "Electric guitar",
        image: "img/guitar.svg"
    }
    Object {
        name: "Bass guitar",
        image: "img/bass.svg"
    }
    // and so on..
}

Currently, I print data by populating an array like this:

var rows = [];
    for (var obj in this.state.instruments[0]) {
        rows.push(<Instrument name={this.state.instruments[0][obj].name}
                              image={this.state.instruments[0][obj].image}/>);
    }

I feel like there's a better way to do it, can somedody give a hint? Thanks

3 Answers 3

2

I user firebase a lot and mu solution is little ES6 helper function

const toArray = function (firebaseObj) {

return Object.keys(firebaseObj).map((key)=> {
    return Object.assign(firebaseObj[key], {key});
})

};

I also assign the firebase key to object key property, so later I can work with the keys.

Sign up to request clarification or add additional context in comments.

Comments

1

The native map function only works for arrays, so using directly it on this object won't work.

What you can do instead is:

Call the map function on the keys of your object using Object.keys():

getInstrumentRows() {
  const instruments = this.state.instruments;
  Object.keys(instruments).map((key, index) => {
    let instrument = instruments[key];
    // You can now use instrument.name and instrument.image
    return  <Instrument name={instrument.name} image={instrument.image}/>
  });
}


Alternatively, you can also import the lodash library and use its map method which would allow you to refactor the above code into:

getInstrumentRowsUsingLodash() {
  const instruments = this.state.instruments;
    _.map(instruments, (key, index) => {
    let instrument = instruments[key];
    // You can now use instrument.name and instrument.image
    return  <Instrument name={instrument.name} image={instrument.image}/>
  });
}

Side note: When you retrieve you data from Firebase you attempt to update the state directly with a call on this.state.instruments. The state in React should be treated as Immutable and should not be mutated with direct calls to it like push.

2 Comments

Thanks! I used the first solution and I could finally access the instrument properties!
Glad I could help :-)
0

I would use map function:

_getInstrumentRows() {
    const instruments = this.state.instruments[0];
    if (instruments) {
        return instruments.map((instrument) => 
            <Instrument name={instrument.name}
                        image={instrument.image}/>);
    }
}

In your render() method you just use {_getInstrumentRows()} wherever you need it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.