Jakub Kašpar
Jakub Kašpar

Reputation: 285

React and Firebase - how to count based on property value

I am trying to count done tasks. I am fetching whole data because I am also rendering it. After componentDidMount I have all data stored in state object like so:

enter image description here

The componentDidMount looks like this:

  componentDidMount () {
    const dataGoalRef = dbRef.child('goals/'+this.state.uid+'/'+this.state.currentGoalId);
    dataGoalRef.on('value', snap => {
        this.setState({
          dataGoal: snap.val(),
          currentGoalId: this.props.match.params.goalId,
        });
    });
  }

I am already counting the tasks with {this.state.allTasksCount++} but it fires every time component gets rendered it.

render() {
    return(
      <div>
        <main className="content">
          <p>{this.state.dataGoal.description}</p><br /><br />


            { this.state.dataGoal.milestones &&
              Object.keys(this.state.dataGoal.milestones).map( (milestoneKey) => {
              const milestonesData = this.state.dataGoal.milestones[milestoneKey];
              console.log(this.doneTasksFromDataGoal());

              return <div className="milestone-wrap" key={milestoneKey}>
                       <label className="milestone-label truncate">{milestonesData.name}</label>

                       {Object.keys(milestonesData.tasks)
                         .filter( (taskKey, index) => {
                           {this.state.allTasksCount++}
                           return milestonesData.tasks[taskKey].done === false;
                         })
                         .map( (taskKey) => {

                           {this.state.todoTasksCount++}
                           return <div className="task clearfix" key={taskKey}>

                                       <input
                                         className="checkbox-rounded"
                                         name="done"
                                         type="checkbox"
                                         checked={milestonesData.tasks[taskKey].done}
                                         onChange={(e) => this.handleInputChange(e, milestoneKey, taskKey)} />
                                       <div className="task-content">
                                         <p className="task-name truncate">{milestonesData.tasks[taskKey].name}</p>
                                         <p className="task-date">{milestonesData.tasks[taskKey].finishDate}</p>
                                       </div>
                                  </div>

                         })}

                     </div>

            })}

        </main>
      </div>
    );
  }

What is the best way to get the number of done or not done tasks and keep it in state?

Upvotes: 2

Views: 1114

Answers (2)

Troy Carlson
Troy Carlson

Reputation: 3121

Here is a really verbose solution to iterate the milestones and tasks and increment a counter inside of the render() function:

render() {
    var doneCount = 0;
    var milestones = this.state.dataGoal.milestones;

    Object.keys(milestones).forEach(function(milestoneKey) {
        Object.keys(milestones[milestoneKey].tasks).forEach(function(taskKey) {
            if (milestones[milestoneKey].tasks[taskKey].done) {
                doneCount += 1;
            }
        });
    });

    return (
        <div>Done: {doneCount}</div>
    );
}

Upvotes: 1

Shahzad
Shahzad

Reputation: 131

Try componentWillRecieveProps. It will be called whenever props are changed after mounting has been completed. Also here you can compare previous and next props. And this is the preferred place to call setState, by using which you can update done counter.

Please comment if you need detailed explanation.

Upvotes: 0

Related Questions