Skip to content

Instantly share code, notes, and snippets.

@jssee
Last active January 21, 2018 23:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jssee/197d5263078a621a0baa71b27260762e to your computer and use it in GitHub Desktop.
Save jssee/197d5263078a621a0baa71b27260762e to your computer and use it in GitHub Desktop.
Choo first app
const extend = require("xtend");
const choo = require("choo");
const html = require("choo/html");
const app = choo();
app.use({
state: {
todos: []
},
reducers: {
receiveTodos: (state, data) => {
return { todos: data };
},
receiveNewTodo: (state, data) => {
const newTodos = state.todos.slice();
newTodos.push(data);
return { todos: newTodos };
},
replaceTodo: (state, data) => {
const newTodos = state.todos.slice();
newTodos[data.index] = data.todo;
return { todos: newTodos };
}
},
effects: {
getTodos: (state, data, send, done) => {
store.getAll("todos", todos => {
send("receiveTodos", todos, done);
});
},
addTodo: (state, data, send, done) => {
const todo = extend(data, {
completed: false
});
store.add("todos", todo, () => {
send("receiveNewTodo", todo, done);
});
},
updateTodo: (state, data, send, done) => {
const oldTodo = state.todos[data.index];
const newTodo = extend(oldTodo, data.updates);
store.replace("todos", data.index, newTodo, () => {
send("replaceTodo", { index: data.index, todo: newTodo }, done);
});
}
}
});
const view = (state, prev, send) => {
return html`
<div onload=${() => send("getTodos")}>
<form onsubmit=${onSubmit}>
<input type="text" placeholder="New item" id="title">
</form>
<ul>
${state.todos.map(
(todo, index) => html`
<li>
<input type="checkbox" ${
todo.completed ? "checked" : ""
} onchange=${e => {
const updates = { completed: e.target.checked };
send("updateTodo", { index: index, updates: updates });
}} />
${todo.title}
</li>`
)}
</ul>
</div>`;
function onSubmit(e) {
const input = e.target.children[0];
send("addTodo", { title: input.value });
input.value = "";
e.preventDefault();
}
};
app.route([["/", view]]);
const tree = app.start();
document.body.appendChild(tree);
// localStorage wrapper
const store = {
getAll: (storeName, cb) => {
try {
cb(JSON.parse(window.localStorage[storeName]));
} catch (e) {
cb([]);
}
},
add: (storeName, item, cb) => {
store.getAll(storeName, items => {
items.push(item);
window.localStorage[storeName] = JSON.stringify(items);
cb();
});
},
replace: (storeName, index, item, cb) => {
store.getAll(storeName, items => {
items[index] = item;
window.localStorage[storeName] = JSON.stringify(items);
cb();
});
}
};
{
"name": "choo-t",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "bankai start index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"choo": "^6.7.0",
"xtend": "^4.0.1"
},
"devDependencies": {
"bankai": "^9.3.1"
}
}
@jssee
Copy link
Author

jssee commented Jan 21, 2018

when I try to start the dev server I get this error in the console.

TypeError: app.model is not a function. (In 'app.model({
  state: {
    todos: [{ title: "Buy milk" }, { title: "Call mum" }]
  }
})', 'app.model' is undefined)

A few notes:

  1. instead of using budo I used the npm start script that comes with create-choo-app, I also tried globally installing budo and it still gives em the same error.
  2. I directly copied and pasted the sample code on the handbook, I noticed it uses app.router() instead of app.route() like in create-choo-app, is this intentional? there are a few differences between this and create-choo-app but not sure if those are intentional. FWIW create-choo-app works fine for me.

@yoshuawuyts
Copy link

Hey, so it's supposed to be app.use() and app.route(). Sorry it hasn't been updated properly!

@jssee
Copy link
Author

jssee commented Jan 21, 2018

made those edits and now im getting this error

AssertionError: choo.use: cb should be type function

edit: I updated the index.js to just be a straight copy of the final sample code on the Choo first app page. made the use and route changes as well, also added xtend to the dependencies just like in the demo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment