Skip to content

Commit

Permalink
Phase 6 - Use v-model axios rest wrapper. Add error checking
Browse files Browse the repository at this point in the history
1. `npm install v-model --save` or modify package.json per example and run npm install
2. added todoModel.js to replace the axios based todoRestApi from phase 5
3. modified main.js to use todoModel and the [vmodel](https://github.com/laoshu133/v-model) Model based methods
4. Add some error checking with `catch` and a div in index.html to diplay errors
5. Modify the Todo domain in grails so we can simulate an error by creaating an item with 'xxx'
  • Loading branch information
basejump committed May 9, 2017
1 parent c70c3ea commit b657f26
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 20 deletions.
2 changes: 1 addition & 1 deletion grails-server/grails-app/domain/grails/server/Todo.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Todo {
Boolean archived = false

static constraints = {
title nullable: false
title nullable: false, notEqual: "xxx"
completed nullable: false
archived nullable: false
}
Expand Down
2 changes: 1 addition & 1 deletion vue-app/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {
// add your custom rules here
'rules': {
'spaced-comment': 0,
'quotes':0, "space-before-function-paren":0,
'quotes':0, 'space-before-function-paren':0, 'semi':0,
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
Expand Down
1 change: 1 addition & 0 deletions vue-app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<div v-show="errors.message" style="padding:5px;border:1px solid orange; color:#c4641b"><p>{{ errors.message }}</p></div>
<input class="new-todo"
autofocus autocomplete="off"
placeholder="What needs to be done?"
Expand Down
5 changes: 3 additions & 2 deletions vue-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
},
"dependencies": {
"axios": "^0.16.1",
"todomvc-app-css": "2.0.6",
"v-model": "0.0.4",
"vue": "^2.2.6",
"vue-router": "^2.3.1",
"todomvc-app-css": "2.0.6"
"vue-router": "^2.3.1"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
Expand Down
41 changes: 25 additions & 16 deletions vue-app/src/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Vue from 'vue'
import todoApi from './todoRestApi'
import TodoModel from './todoModel'

import '../node_modules/todomvc-app-css/index.css'
// import './styles/styles.scss'
Expand Down Expand Up @@ -31,7 +31,8 @@ var app = new Vue({
todos: [],
newTodo: '',
editedTodo: null,
visibility: 'all'
visibility: 'all',
errors: TodoModel.errors
},

// watch todos change for localStorage persistence
Expand Down Expand Up @@ -61,7 +62,7 @@ var app = new Vue({
this.todos.forEach(function (todo) {
todo.completed = value
})
todoApi.updateAll(this.todos)
TodoModel.updateAll(this.todos)
}
}
},
Expand All @@ -76,21 +77,25 @@ var app = new Vue({
// note there's no DOM manipulation here at all.
methods: {
addTodo: function () {
let self = this

var value = this.newTodo && this.newTodo.trim()
if (!value) {
return
}
var newTodoObj = {
title: value,
completed: false
}
todoApi.save(newTodoObj)
this.todos.push(newTodoObj)
this.newTodo = ''
},

let newTodoObj = TodoModel.save({
title: value
})

newTodoObj.$promise.then(function (response) {
self.todos.push(newTodoObj)
console.log("addTodo ", newTodoObj)
self.newTodo = ''
})
},
removeTodo: function (todo) {
todoApi.delete(todo)
todo.$delete()
this.todos.splice(this.todos.indexOf(todo), 1)
},

Expand All @@ -108,7 +113,10 @@ var app = new Vue({
if (!todo.title) {
this.removeTodo(todo)
} else {
todoApi.update(todo)
let self = this
todo.$update().catch(function (ex) {
self.editedTodo = todo //reset it back so input doesn't go away
})
}
},

Expand All @@ -118,12 +126,12 @@ var app = new Vue({
},

removeCompleted: function () {
todoApi.archiveCompleted(this.todos)
TodoModel.archiveCompleted(this.todos)
},

setCompleted: function(todo) {
todo.completed = !todo.completed
todoApi.update(todo)
todo.$update()
}
},

Expand All @@ -140,7 +148,8 @@ var app = new Vue({

created: function() {
console.log("Ready")
todoApi.list(this.todos)
this.todos = TodoModel.query()
//TodoModel.list(this.todos)
}
})

Expand Down
38 changes: 38 additions & 0 deletions vue-app/src/todoModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Model from 'v-model'
import Promise from 'bluebird'

// set baseURL and install plugin
Model.http.defaults.baseURL = 'http://localhost:8080/api/';

const TodoModel = Model.extend('/todo/:id')

TodoModel.updateAll = todos => {
todos.forEach(function (todo) {
todo.$update()
})
}

TodoModel.archiveCompleted = todos => {
todos.filter(function (todo) {
return todo.completed
}).forEach(function (todo) {
todo.$delete().then(response => {
todos.splice(todos.indexOf(todo), 1)
//console.log("deleted", todo)
})
})
}

TodoModel.errors = { message: '' } //set to data.

// Add a response interceptor for default errors from Grails rest
TodoModel.http.interceptors.response.use(function (response) {
TodoModel.errors.message = ''
return response
}, function (error) {
console.log("error.response ", error.response)
TodoModel.errors.message = error.response.data.message
return Promise.reject(error)
})

export default TodoModel

0 comments on commit b657f26

Please sign in to comment.