## 4: Update and Remove

Up until now, you have only inserted documents into our collection. Let's take a look at how you can update and remove them by interacting with the user interface.

### 4.1: Add Checkbox

First, you need to add a `checkbox` element to your `Task` component.

Next, let’s create a new file for our `task` in `imports/ui/Task.jsx`, so we can start to separate the logic in our app.

::: code-group

```jsx [imports/ui/Task.jsx]
import { Meteor } from "meteor/meteor";

export const Task = (props) => {
  const { task } = props;

  const toggleChecked = async () => {
    await Meteor.callAsync("tasks.toggleChecked", { _id: task._id, isChecked: task.isChecked });
  };

  return (
    <li>
      <label>
        <input type="checkbox" checked={task.isChecked} onChange={toggleChecked} />
        <span>{task.text}</span>
      </label>
    </li>
  );
};
```
:::

Now, update `App.jsx` to import and use the `Task` component in the `<For>` loop. Remove the old `<li>` markup.

::: code-group

```jsx [imports/ui/App.jsx]
import { createSignal, For, Show } from "solid-js";
import { Meteor } from "meteor/meteor";
import { Tracker } from "meteor/tracker";
import { TasksCollection } from "../api/TasksCollection";
import { Task } from "./Task.jsx"; // [!code highlight]

export const App = () => {
  const [newTask, setNewTask] = createSignal('');

  const addTask = async (event) => {
    event.preventDefault();
    if (newTask().trim()) {
      await Meteor.callAsync("tasks.insert", {
        text: newTask(),
        createdAt: new Date(),
      });
      setNewTask('');
    }
  };

  const subscription = Meteor.subscribe("tasks");
  const [isReady, setIsReady] = createSignal(subscription.ready());
  const [tasks, setTasks] = createSignal([]);

  Tracker.autorun(async () => {
    setIsReady(subscription.ready());
    setTasks(await TasksCollection.find({}, { sort: { createdAt: -1 } }).fetchAsync());
  });

  return (
    <div class="container">
      <header>
        <h1>Todo List</h1>
      </header>

      <form class="task-form" onSubmit={addTask}>
        <input
          type="text"
          placeholder="Type to add new tasks"
          value={newTask()}
          onInput={(e) => setNewTask(e.currentTarget.value)}
        />
        <button type="submit">Add Task</button>
      </form>

      <Show
        when={isReady()}
        fallback={<div>Loading ...</div>}
      >
        <ul>
          <For each={tasks()}>
            {(task) => (
              <Task task={task} /> // [!code highlight]
            )}
          </For>
        </ul>
      </Show>
    </div>
  );
};
```
:::

### 4.2: Toggle Checkbox

Now you can update your task document by toggling its `isChecked` field.

First, create a new method called `tasks.toggleChecked` to update the `isChecked` property.

::: code-group

```js [imports/api/TasksMethods.js]
import { Meteor } from "meteor/meteor";
import { TasksCollection } from "./TasksCollection";

Meteor.methods({
  ...
  "tasks.toggleChecked"({ _id, isChecked }) {
    return TasksCollection.updateAsync(_id, {
      $set: { isChecked: !isChecked },
    });
  },
});
```
:::

In `Task.jsx` (as shown above), we've added an `onChange` handler that calls the method to toggle the checked state.

Toggling checkboxes should now persist in the DB even if you refresh the web browser. 

Your app should look like this:

<img width="200px" src="/tutorials/solid/assets/step04-checkbox.png"/>

If your computer is fast enough, it's possible that when it sets up the default tasks a few will have the same date. That will cause them to non-deterministically "jump around" in the UI as you toggle checkboxes and the UI reactively updates. To make it stable, you can add a secondary sort on the `_id` of the task:

::: code-group

```jsx [imports/ui/App.jsx]
...

Tracker.autorun(async () => {
  setIsReady(subscription.ready());
  setTasks(await TasksCollection.find({}, { sort: { createdAt: -1, _id: -1 } }).fetchAsync()); // [!code highlight]
});

...
```
:::


### 4.3: Remove tasks

You can remove tasks with just a few lines of code.

First, add a button after the `label` in your `Task` component and a `deleteTask` function.

::: code-group

```jsx [imports/ui/Task.jsx]
import { Meteor } from "meteor/meteor";

export const Task = (props) => {
  const { task } = props;

  const toggleChecked = async () => {
    await Meteor.callAsync("tasks.toggleChecked", { _id: task._id, isChecked: task.isChecked });
  };

  const deleteTask = async () => { // [!code highlight]
    await Meteor.callAsync("tasks.delete", { _id: task._id }); // [!code highlight]
  }; // [!code highlight]

  return (
    <li>
      <label>
        <input type="checkbox" checked={task.isChecked} onChange={toggleChecked} />
        <span>{task.text}</span>
      </label>

      <button class="delete" onClick={deleteTask}>&times;</button> // [!code highlight]
    </li>
  );
};
```
:::

Next you need to have a function to delete the task. For that, let's create a new method called `tasks.delete`:

::: code-group

```js [imports/api/TasksMethods.js]
import { Meteor } from "meteor/meteor";
import { TasksCollection } from "./TasksCollection";

Meteor.methods({
  ...
  "tasks.delete"({ _id }) {
    return TasksCollection.removeAsync(_id);
  },
});
```
:::

Now the removal logic is handled in `Task.jsx` via the `onClick` event on the delete button, which calls the Meteor method.

Your app should look like this:

<img width="200px" src="/tutorials/solid/assets/step04-delete-button.png"/>

### 4.4: Getting data in event handlers

In a collection, every inserted document has a unique `_id` field that can refer to that specific document. Inside the component, the `task` prop provides access to the task object, including its `_id`
and other fields like `isChecked` and `text`. We use these to call Meteor methods for updating or removing the specific task.

In the next step, we are going to improve the look of your app using CSS with Flexbox.

