---
title: Bitovi Academy - Setter Toggle
description: Toggle all todos complete state (DefineMap setter)
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting?hsLang=en-us)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting?hsLang=en-us)
- ![Project management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project management](https://www.bitovi.com/services/agile-project-management-consulting?hsLang=en-us)
- ![Product design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product design](https://www.bitovi.com/services/product-design-consulting?hsLang=en-us)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services?hsLang=en-us)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting?hsLang=en-us)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers?hsLang=en-us)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting?hsLang=en-us)
- [Design Systems](https://www.bitovi.com/services/axure-figma-migration?hsLang=en-us)
- [React](https://www.bitovi.com/services/frontend/react-consulting?hsLang=en-us)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting?hsLang=en-us)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native?hsLang=en-us)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting-1?hsLang=en-us)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study?hsLang=en-us)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign?hsLang=en-us)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp?hsLang=en-us)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work?hsLang=en-us)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source?hsLang=en-us)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about perfecting software delivery
  
  ](https://bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships?hsLang=en-us)
- [![Academy](https://www.bitovi.com/hubfs/limbo/icons/icon-academy.svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy/?hsLang=en-us)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse our tools or contribute to our open source mission.
  
  ](https://www.bitovi.com/open-source?hsLang=en-us)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

- [ Advanced JavaScript ](https://www.bitovi.com/academy/learn-advanced-javascript.html?hsLang=en-us)
- [ DOM and jQuery ](https://www.bitovi.com/academy/learn-dom-jquery.html?hsLang=en-us)
- [ Debug JavaScript ](https://www.bitovi.com/academy/learn-to-debug-javascript.html?hsLang=en-us)
- [ Learn TypeScript ](https://www.bitovi.com/academy/learn-typescript.html?hsLang=en-us)
- [ Learn React Native ](https://www.bitovi.com/academy/learn-react-native.html?hsLang=en-us)
- [ Learn Web Components ](https://www.bitovi.com/academy/learn-web-components.html?hsLang=en-us)
- [ Agile Program Management With Jira ](https://www.bitovi.com/academy/learn-agile-program-management-with-jira.html?hsLang=en-us)
- [ Learn RxJS ](https://www.bitovi.com/academy/learn-rxjs.html?hsLang=en-us)
- [ Giving a Training ](https://www.bitovi.com/academy/training.html?hsLang=en-us)
- [ Learn Technology Consulting ](https://www.bitovi.com/academy/learn-technology-consulting.html?hsLang=en-us)
- [ Learn React ](https://www.bitovi.com/academy/learn-react.html?hsLang=en-us)
- [ Learn NgRx ](https://www.bitovi.com/academy/learn-ngrx.html?hsLang=en-us)
- [ Learn Graphql ](https://www.bitovi.com/academy/learn-graphql.html?hsLang=en-us)
- [ Learn Docker ](https://www.bitovi.com/academy/learn-docker.html?hsLang=en-us)
- [ Learn CanJS ](https://www.bitovi.com/academy/learn-canjs.html?hsLang=en-us) 
    - [ Setup with StealJS ](https://www.bitovi.com/academy/learn-canjs/setup-canjs.html?hsLang=en-us)
    - [ Define Todo Model ](https://www.bitovi.com/academy/learn-canjs/define-todo.html?hsLang=en-us)
    - [ Define Todo List ](https://www.bitovi.com/academy/learn-canjs/define-todo-list.html?hsLang=en-us)
    - [ Render Todos ](https://www.bitovi.com/academy/learn-canjs/render-todos.html?hsLang=en-us)
    - [ Toggle checkbox ](https://www.bitovi.com/academy/learn-canjs/toggle-event.html?hsLang=en-us)
    - [ Toggle checkbox ](https://www.bitovi.com/academy/learn-canjs/toggle-data.html?hsLang=en-us)
    - [ Algebra ](https://www.bitovi.com/academy/learn-canjs/algebra.html?hsLang=en-us)
    - [ Simulate the service layer ](https://www.bitovi.com/academy/learn-canjs/simulate-service-layer.html?hsLang=en-us)
    - [ Connection ](https://www.bitovi.com/academy/learn-canjs/connection.html?hsLang=en-us)
    - [ Connection List ](https://www.bitovi.com/academy/learn-canjs/connection-list.html?hsLang=en-us)
    - [ Toggle Save ](https://www.bitovi.com/academy/learn-canjs/toggle-save.html?hsLang=en-us)
    - [ Connection Destroy ](https://www.bitovi.com/academy/learn-canjs/connection-destroy.html?hsLang=en-us)
    - [ Component Create ](https://www.bitovi.com/academy/learn-canjs/component-create.html?hsLang=en-us)
    - [ Component Edit ](https://www.bitovi.com/academy/learn-canjs/component-edit.html?hsLang=en-us)
    - [ Setter Toggle ](https://www.bitovi.com/academy/learn-canjs/setter-toggle.html?hsLang=en-us)
    - [ Clear All Completed ](https://www.bitovi.com/academy/learn-canjs/clear-all-completed.html?hsLang=en-us)
    - [ Routing ](https://www.bitovi.com/academy/learn-canjs/routing.html?hsLang=en-us)
- [ Learn Angular ](https://www.bitovi.com/academy/learn-angular.html?hsLang=en-us)
- [ Advanced TypeScript ](https://www.bitovi.com/academy/advanced-typescript.html?hsLang=en-us)

[View More Courses](https://www.bitovi.com/academy/#courses) [ ]

# Setter Toggle `page`

Toggle all todos complete state (DefineMap setter)

## The problem

Make the “toggle all” checkbox work. It should be unchecked if a single todo is unchecked and checked if all todos are checked.

When the “toggle all” checkbox is changed, the application should update every todo to match the status of the “toggle all” checkbox.

The “toggle all” checkbox should be disabled if a single todo is saving.

## What you need to know

- Using [setters](https://canjs.com/doc/can-define.types.set.html) and [getters](https://canjs.com/doc/can-define.types.get.html) a virtual property can be simulated like:
  
  ```
  DefineMap.extend({
      first: "string",
      last: "string",
      get fullName() {
          return this.first + " " + this.last;
      },
      set fullName(newValue) {
          const parts = newValue.split(" ");
          this.first = parts[0];
          this.last = parts[1];
      }
  })
  ```

## The solution

Click to see the solution

Update *models/todo.js* to the following:

```
// models/todo.js
import {DefineMap, DefineList, realtimeRestModel} from "can";

const Todo = DefineMap.extend("Todo", {
    id: {type: "string", identity: true},
    name: "string",
    complete: {
        type: "boolean",
        default: false
    },
    toggleComplete() {
        this.complete = !this.complete;
    }
});

Todo.List = DefineList.extend("TodoList", {
    "#": Todo,
    get active() {
        return this.filter({
            complete: false
        });
    },
    get complete() {
        return this.filter({
            complete: true
        });
    },
    get allComplete() {
        return this.length === this.complete.length;
    },
    get saving() {
        return this.filter(function(todo) {
            return todo.isSaving();
        });
    },
    updateCompleteTo(value) {
        this.forEach(function(todo) {
            todo.complete = value;
            todo.save();
        });
    }
});

Todo.connection = realtimeRestModel({
    url: "/api/todos/{id}",
    Map: Todo,
    List: Todo.List
});

export default Todo;

```

Update *index.js* to the following:

```
// index.js
import {Component} from "can";
import view from "./index.stache";
import Todo from "~/models/todo";
import "~/models/todos-fixture";
import test from "can-todomvc-test";

Component.extend({
    tag: "todo-mvc",
    view,
    ViewModel: {
        appName: {default: "TodoMVC"},
        todosList: {
            get: function(lastSet, resolve) {
                Todo.getList({}).then(resolve);
            }
        },
        get allChecked() {
            return this.todosList && this.todosList.allComplete;
        },
        set allChecked(newVal) {
            this.todosList && this.todosList.updateCompleteTo(newVal);
        }
    }
});

const appVM = window.appVM = document.querySelector("todo-mvc").viewModel;

test(appVM);

```

Update *index.stache* to the following:

```
<!-- index.stache -->
<can-import from="~/components/todo-create/" />
<can-import from="~/components/todo-list/" />
<section id="todoapp">
    <header id="header">
        <h1>{{ this.appName }}</h1>
        <todo-create/>
    </header>
    <section id="main" class="">
        <input id="toggle-all" type="checkbox"
            checked:bind="this.allChecked"
            disabled:from="this.todosList.saving.length" />
        <label for="toggle-all">Mark all as complete</label>
        <todo-list todos:from="this.todosList" />
    </section>
    <footer id="footer" class="">
        <span id="todo-count">
            <strong>{{ this.todosList.active.length }}</strong> items left
        </span>
        <ul id="filters">
            <li>
                <a class="selected" href="#!">All</a>
            </li>
            <li>
                <a href="#!active">Active</a>
            </li>
            <li>
                <a href="#!completed">Completed</a>
            </li>
        </ul>
        <button id="clear-completed">
            Clear completed ({{ this.todosList.complete.length }})
        </button>
    </footer>
</section>

```

###### On this page...

###### Get help

If you need [help](https://discord.gg/J7ejFsZnJ4) with an exercise, please reach out to us on [Discord](https://discord.gg/J7ejFsZnJ4)

If you find a bug, please [create an issue](https://github.com/bitovi/academy/issues/new) or email [contact@bitovi.com](mailto:contact@bitovi.com?Subject=Training%20Suggestion)

## Join the Bitovi Newsletter

 Do you want to receive updates about new Bitovi Academy courses, Bitovi open source projects, and dev community news? If so, please provide your email. We won’t spam you or give it away for any reason!  
*By providing your email you agree to receive communications from Bitovi*

![](https://bitovi.github.io/academy/static/img/close.svg)

```json
{
     "@context": "http://schema.org",
     "@type": "Organization",
     "mainEntityOfPage":{
          "@type":"WebPage",
          "@id":"https://www.bitovi.com/academy/learn-canjs/setter-toggle.html",
          "description": "Toggle all todos complete state (DefineMap setter) 
"
     },
     "url": "http://bitovi.com",
     "logo": "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
     "image": "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
     "name": "Bitovi Web App Consulting",
     "alternateName": "Bitovi",
      "naics": "541511",
      "description": "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
     "address": {
          "@type": "PostalAddress",
          "streetAddress": "1134 Pine Tree Lane ",
          "addressLocality": "Libertyville",
          "addressRegion": "IL",
          "addressCountry": "United States",
          "postalCode": "60048"
     },
     "areaServed": {
          "@type": "GeoCircle",
          "geoMidpoint": {
               "@type": "GeoCoordinates",
               "latitude": "41.8781",
               "longitude": "87.6298"
          },
          "geoRadius": "5000 km"
     },
     "telephone": "312-620-0386",
     "email": "contact@bitovi.com",
     "sameAs": [
          "https://www.facebook.com/BitoviLLC/",
          "https://twitter.com/bitovi",
          "https://www.linkedin.com/company/bitovi"
     ]
}
```