Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,851 changes: 1,851 additions & 0 deletions week3/homework/package-lock.json

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions week3/homework/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
{
"name": "hyf-node-week-3-homework",
"version": "1.0.0",
"description": "HackYourFuture Node.js Week 3 - Homework",
"name": "hyf-node-week-3-todo",
"version": "1.0.1",
"description": "HackYourFuture Node.js Week 3 - To-Do App",
"repository": "https://github.com/HackYourFuture/nodejs.git",
"main": "src/index.js",
"author": "George Sapkin",
"license": "MIT",
"scripts": {
"start": "node src/index"
},
"dependencies": {
"express": "^4.16.2",
"uuid": "^3.2.1"
},
"devDependencies": {
"eslint": "^4.2.0",
"eslint-config-standard": "^11.0.0",
Expand Down
15 changes: 15 additions & 0 deletions week3/homework/src/actions/clearTodos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

function clearTodos(todo, request, response) {
todo.clearList()
.then(() => {
response.status(204);
response.end();
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = clearTodos;
18 changes: 18 additions & 0 deletions week3/homework/src/actions/createTodo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

const deserializeTodo = require('./deserializeTodo');

function createTodo(todo, request, response) {
deserializeTodo(request, response)
.then(({ description }) => todo.create(description))
.then(todo => {
response.status(201);
response.json({ todo });
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = createTodo;
17 changes: 17 additions & 0 deletions week3/homework/src/actions/deleteTodo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

function deleteTodo(todo, request, response) {
const id = request.params.id;

todo.delete_(id)
.then(() => {
response.status(204);
response.end();
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = deleteTodo;
17 changes: 17 additions & 0 deletions week3/homework/src/actions/deserializeTodo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

async function deserializeTodo(request) {
const { todo } = request.body;
if (todo == null)
throw new Error('todo not set');

if (todo.description != null)
todo.description = todo.description.trim();

if (todo.description == null || todo.description.length === 0)
throw new Error('description not set');

return todo;
};

module.exports = deserializeTodo;
14 changes: 14 additions & 0 deletions week3/homework/src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

// CRUD actions
module.exports = {
createTodo: require('./createTodo'),
readTodos: require('./readTodos'),
updateTodo: require('./updateTodo'),
deleteTodo: require('./deleteTodo'),
readTodo: require('./readTodo'),
clearTodos: require('./clearTodos'),
markAsDone: require('./markAsDone'),
markAsNotDone: require('./markAsNotDone')

};
17 changes: 17 additions & 0 deletions week3/homework/src/actions/markAsDone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

function markAsDone(todo, request, response) {
const id = request.params.id;
todo.done(id)

.then(todo => {
response.status(200);
response.json({ todo });
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = markAsDone;
17 changes: 17 additions & 0 deletions week3/homework/src/actions/markAsNotDone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

function markAsNotDone(todo, request, response) {
const id = request.params.id;
todo.notDone(id)

.then(todo => {
response.status(200);
response.json({ todo });
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = markAsNotDone;
16 changes: 16 additions & 0 deletions week3/homework/src/actions/readTodo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

function readTodo(todo, request, response) {
const id = request.params.id;
todo.readById(id)
.then(todo => {
response.json({ todo });
response.end();
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = readTodo;
15 changes: 15 additions & 0 deletions week3/homework/src/actions/readTodos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

function readTodos(todo, request, response) {
todo.read()
.then(todos => {
response.json({ todos });
response.end();
})
.catch(({ message }) => {
response.status(500);
response.json({ error: message });
});
};

module.exports = readTodos;
21 changes: 21 additions & 0 deletions week3/homework/src/actions/updateTodo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

const deserializeTodo = require('./deserializeTodo');

function updateTodo(todo, request, response) {
deserializeTodo(request, response)
.then(({ description }) => {
const id = request.params.id;
return todo.update(id, description);
})
.then(todo => {
response.status(200);
response.json({ todo });
})
.catch(({ message, code }) => {
response.status(code === 'not-found' ? 404 : 500);
response.json({ error: message });
});
};

module.exports = updateTodo;
44 changes: 43 additions & 1 deletion week3/homework/src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
'use strict';

// TODO: Write the homework code in this file
const Express = require('express');

// import our CRUD actions
const {
createTodo,
readTodos,
updateTodo,
deleteTodo,
readTodo,
clearTodos,
markAsDone,
markAsNotDone

} = require('./actions');

const Todo = require('./todo');

const FILENAME = 'todos.json';
const PORT = 3000;
const TODO_SLUG = 'todos';

const todo = new Todo(FILENAME);

const app = new Express();

// Use built-in JSON middleware to automatically parse JSON
app.use(Express.json());

app.post(`/${TODO_SLUG}`, createTodo.bind(null, todo));
app.get(`/${TODO_SLUG}`, readTodos.bind(null, todo));
app.put(`/${TODO_SLUG}/:id`, updateTodo.bind(null, todo));
app.delete(`/${TODO_SLUG}/:id`, deleteTodo.bind(null, todo));
app.get(`/${TODO_SLUG}/:id`, readTodo.bind(null, todo));
app.delete(`/${TODO_SLUG}`, clearTodos.bind(null, todo));
app.post(`/${TODO_SLUG}/:id/done`, markAsDone.bind(null, todo));
app.delete(`/${TODO_SLUG}/:id/done`, markAsNotDone.bind(null, todo));

app.listen(PORT, error => {
if (error)
return console.error(error);

console.log(`Server started on http://localhost:${PORT}`);
});
128 changes: 128 additions & 0 deletions week3/homework/src/todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
'use strict';

const fs = require('fs');
const uuid = require('uuid/v4');

const DEFAULT_ENCODING = 'utf8';

class Todo {
constructor(filename) {
this._filename = filename;
}

async create(description) {
const todos = await this.read();

const todo = {
id: uuid(),
done: false,

description
};

todos.push(todo);

await this._save(todos);

return todo;
}

read() {
return new Promise(resolve => {
fs.readFile(this._filename, DEFAULT_ENCODING, (error, data) => {
if (error)
return resolve([]);

return resolve(JSON.parse(data));
});
});
}

async update(id, description) {
const todos = await this.read();

const todo = todos.find(t => t.id === id);
if (todo == null) {
const error = new Error(`To-do with ID ${id} does not exist`);
error.code = 'not-found';
throw error;
}

todo.description = description;

await this._save(todos);

return todo;
}

async delete_(id) {
const todos = await this.read();
const filteredTodos = todos.filter(t => t.id !== id);

return this._save(filteredTodos);
}

// Methods starting with underscore should not be used outside of this class
_save(todos) {
return new Promise((resolve, reject) => {
fs.writeFile(
this._filename,
JSON.stringify(todos, null, 2),
error => error == null
? resolve()
: reject(error)
);
});
}
async clearList() {
const todos = await this.read();
let list = [todos];
list = [];
return this._save(list);
}
async readById(id) {
const todos = await this.read();

const todo = todos.find(t => t.id === id);
if (todo == null) {
const error = new Error(`To-do with ID ${id} does not exist`);
error.code = 'not-found';
throw error;
}
return todo;
}
async done(id) {
const todos = await this.read();

const todo = todos.find(t => t.id === id);
if (todo == null) {
const error = new Error(`To-do with ID ${id} does not exist`);
error.code = 'not-found';
throw error;
}

todo.done = true;

await this._save(todos);

return todo;
}
async notDone(id) {
const todos = await this.read();

const todo = todos.find(t => t.id === id);
if (todo == null) {
const error = new Error(`To-do with ID ${id} does not exist`);
error.code = 'not-found';
throw error;
}

todo.done = false;

await this._save(todos);

return todo;
}
}

module.exports = Todo;
1 change: 1 addition & 0 deletions week3/homework/src/todos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
17 changes: 17 additions & 0 deletions week3/homework/todos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"id": "7857c5ed-3771-4a67-8700-5fe77033e7ac",
"done": false,
"description": "Wash the dishes!"
},
{
"id": "3feabbf8-479e-4617-9bde-e4e63296a665",
"done": false,
"description": "Buy Apples!"
},
{
"id": "1f54ff3b-3f4a-4378-97cf-4841b85df7f7",
"done": false,
"description": "Throw the trash!"
}
]
Loading