2

i have a function

const [tasks, setTasks] = useState([])     

const addTask = (title, role) => {
        const newTasks = [...tasks, { title, role}]
        setTasks(newTasks)
}

every form is submitted, addTask function is create state data containing an array of objects

[
{title: "make a coffee", role: "employee"},
{title: "react the sales target", role: "salesman"},
{title: "clean the room", role: "employee"},
{title: "call the client", role: "boss"},
]

i want to populate task based on role

const TaskList = ({ tasks }) => {
    return (
        <Container>
            <Row>
                {tasks.map((task, index) =>
                        <Col sm="12" md="4">
                            <h4 style={{ textAlign: 'center' }}>
                                {task.role} 
                            </h4>
                            <TaskCard task={task} index={index} />
                        </Col>
                )}
            </Row>
        </Container>
    )
}

const TaskCard = ({ task, index, completeTask, editTask, removeTask }) => {
    return (
        <Container className="mb-3">
            <Card body inverse color={task.completed ? 'success' : 'danger'}>
                <CardText>{task.title}</CardText>
                <p></p>
                <div className="Card-btn">
                    <i className="fas fa-check-circle fa-2x fa-fw" onClick={() => completeTask(index)}></i>
                    <i className="fas fa-pen fa-2x fa-fw" onClick={() => editTask(index)}></i>
                    <i className="fas fa-trash-alt fa-2x fa-fw" onClick={() => removeTask(index)}></i>
                </div>
            </Card>
        </Container>
    )
}

but instead of create a task list column for each role, its create new role card enter image description here

how to populate task in column based by role? should i filter it first?

4
  • That is obvious because your <TaskCard task={task} index={index} /> is inside the map() Commented Apr 3, 2021 at 10:07
  • Are you attempting to fill in the tasks on the card? Commented Apr 3, 2021 at 10:13
  • @EdisonPebojot i do, what i want is grouping tasks by role, if new task have same role, its create a new card below in same column Commented Apr 3, 2021 at 10:16
  • @anggapw Please take a look at my answer below, it should help! Commented Apr 3, 2021 at 12:13

2 Answers 2

1

You need modify your task array a bit. You need group the data by role. And for this purpose I would recommend using a Map.

const tasks = [
  { title: 'make a coffee', role: 'employee' },
  { title: 'react the sales target', role: 'salesman' },
  { title: 'clean the room', role: 'employee' },
  { title: 'call the client', role: 'boss' },
];

const m = new Map();

for (const task of tasks) {
  const {role, title} = task;
  if (m.has(role)) {
    const temp = m.get(role);
    m.set(role, [...temp, title]) 
  }else {
    m.set(role, [title])
  }
}

console.log(m);

Now you can loop over the map and for every role there would be an array of tasks which you can again loop over to create Task cards.

Take a look at the following code snippet:

const tasks = [
  { title: "make a coffee", role: "employee" },
  { title: "react the sales target", role: "salesman" },
  { title: "clean the room", role: "employee" },
  { title: "call the client", role: "boss" },
];

function App() {
  const renderItems = () => {
    const m = new Map();
    for (const task of tasks) {
      const { role, title } = task;
      if (m.has(role)) {
        const temp = m.get(role);
        m.set(role, [...temp, title]);
      } else {
        m.set(role, [title]);
      }
    }

    const renderArr = [];
    for (let item of m) {
      renderArr.push(<TaskList role={item[0]} />);
      for (let it of item[1]) {
        renderArr.push(<TaskCard task={it} />);
      }
    }
    return renderArr;
  };

  return renderItems();
}

const TaskList = ({ role }) => <h1>{role}</h1>;

const TaskCard = ({ task }) => <p>{task}</p>;

ReactDOM.render(<App />, document.getElementById("react"));
<div id="react"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

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

Comments

1

you can use loadash to group the array by role then iterate over role's and then iterate over each roles jobs , you'll have to modify my code to fit your col and row syntax .

import _ from 'lodash';

const TaskList = ({ tasks }) => {
    return (
        <Container>
 const groupedByRole = _.chain(tasks).groupBy("role").map((value, key) => ({ role: key, jobs: value }))
  .value()
  return (
    <div >
       {
         groupedByRole.map((role,index)=><div key={index} >
               <h4 style={{ textAlign: 'center' }}> {role.role}  </h4>
                {
                  role.jobs.map((job,index)=><TaskCard key={index}  task={job.title} index={index} />)
                }
           </div>)
       }
    </div>
       </Container>
    )
}

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.