Define Todo Model page
Learn how to create an observable type in CanJS.
The problem
- Define a 
Todotype as the export of models/todo.js, where:- It is a DefineMap type.
 - The id or name property values are coerced into a string.
 - Its 
completeproperty is aBooleanthat defaults tofalse. - It has a 
toggleCompletemethod that flipscompleteto the opposite value. 
 
Example test code:
const todo = new Todo({id: 1, name: 2});
QUnit.equal(todo.id, "1", "id is a string");
QUnit.equal(todo.name, "2", "name is a string");
QUnit.equal(todo.complete, false, "complete defaults to false");
todo.toggleComplete();
QUnit.equal(todo.complete, true, "toggleComplete works");
What you need to know
DefineMap.extend defines a new
Type.import {DefineMap} from "can"; const MyType = DefineMap.extend("MyType",{}); var instance = new MyType(); console.log( instance instanceof MyType ) // Logs true
import {DefineMap} from "can";
const Person = DefineMap.extend("Person",{
    age: {type: "number"}
});
console.log( new Person({age: "3"}).age ) // Logs 3
  
The default behavior defines a property’s initial value like:
import {DefineMap} from "can"; const Person = DefineMap.extend("Person",{ age: {default: 3} }); console.log( new Person().age ) // Logs 3
Methods can be defined directly on the prototype like:
import {DefineMap} from "can"; const Type = DefineMap.extend("Type",{ methodName() { console.log("run method"); } }); var instance = new Type(); instance.methodName() // Logs "run method"
The solution
Click to see the solution
Create models/todo.js as follows:
// models/todo.js
import {DefineMap} from "can";
const Todo = DefineMap.extend("Todo", {
    id: "string",
    name: "string",
    complete: {
        type: "boolean",
        default: false
    },
    toggleComplete() {
        this.complete = !this.complete;
    }
});
export default Todo;