Added better error handling and wired book updates

pull/1/head
androiddrew 7 years ago
parent e9e2d7cb81
commit c7d9df7619

@ -19,28 +19,40 @@ axios.interceptors.request.use(function (config) {
const appService = {
getPing() {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
axios.get('/ping')
.then(response => {
resolve(response.data)
})
.catch(error => {alert(error)})
.catch(error => { reject(error.status)} )
})
},
getAllBooks() {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
axios.get('/books')
.then(response => {
resolve(response.data)
})
.catch(error => {alert(error)})
.catch(error => { reject(error.status)} )
})
},
addBook(payload) {
return new Promise((resolve, reject) => {
axios.post('/books', payload)
.then(response => { resolve(response.data)})
.catch(response => { reject(response.status)} )
.catch(error => { reject(error.status)} )
})
},
updateBook(book) {
return new Promise((resolve, reject) => {
axios.put(`/books/${book.id}`, book)
.then(response => {
resolve(response.data)
})
.catch(error => {
console.log(`Error in book update: ${error}`)
reject(error.status)
})
})
},
}

@ -1,6 +1,6 @@
<template>
<div>
<b-alert variant="success"
<b-alert :variant="variant"
:show="dismissSecs"
dismissible
@dismissed="dismissAlert"
@ -12,7 +12,7 @@
<script>
export default {
props: ['message'],
props: ['message', 'variant'],
data () {
return {
dismissSecs: 5,

@ -5,7 +5,7 @@
<h1>Books</h1>
<hr>
<br><br>
<alert :message="message" v-if="showMessage" v-on:alert-closed="showMessage = !showMessage"></alert>
<alert :variant="alertVariant" :message="message" v-if="showMessage" v-on:alert-closed="showMessage = !showMessage"></alert>
<button type="button" class="btn btn-success btn-sm" v-b-modal.book-modal>Add Book</button>
<br><br>
<table class="table table-hover">
@ -26,7 +26,7 @@
<span v-else>No</span>
</td>
<td>
<button type="button" class="btn btn-warning btn-sm">Update</button>
<button type="button" class="btn btn-warning btn-sm" v-b-modal.book-update-modal @click="editBook(book)">Update</button>
<button type="button" class="btn btn-danger btn-sm">Delete</button>
</td>
</tr>
@ -68,6 +68,40 @@
<b-button type="reset" variant="danger">Reset</b-button>
</b-form>
</b-modal>
<b-modal ref="editBookModal"
id="book-update-modal"
title="Update"
hide-footer>
<b-form @submit.prevent="onSubmitUpdate" @reset.prevent="onResetUpdate" class="w-100">
<b-form-group id="form-title-edit-group"
label="Title:"
label-for="form-title-edit-input">
<b-form-input id="form-title-edit-input"
type="text"
v-model="editForm.title"
required
placeholder="Enter title">
</b-form-input>
</b-form-group>
<b-form-group id="form-author-edit-group"
label="Author:"
label-for="form-author-edit-input">
<b-form-input id="form-author-edit-input"
type="text"
v-model="editForm.author"
required
placeholder="Enter author">
</b-form-input>
</b-form-group>
<b-form-group id="form-read-edit-group">
<b-form-checkbox-group v-model="editForm.read" id="form-checks">
<b-form-checkbox value="true">Read?</b-form-checkbox>
</b-form-checkbox-group>
</b-form-group>
<b-button type="submit" variant="primary">Update</b-button>
<b-button type="reset" variant="danger">Cancel</b-button>
</b-form>
</b-modal>
</div>
</template>
@ -96,21 +130,37 @@ export default {
read: [],
},
message: '',
alertVariant: '',
showMessage: false,
editForm: {
id: '',
title: '',
author: '',
read: [],
},
}
},
methods:{
...mapActions(['LOAD_BOOKS_LIST', 'POST_BOOK']),
...mapActions(['LOAD_BOOKS_LIST', 'POST_BOOK', 'PUT_BOOK']),
initForm(){
this.addBookForm.title = ''
this.addBookForm.author = ''
this.addBookForm.read = []
this.addBookForm.read = [];
this.editForm.id = '';
this.editForm.title = '';
this.editForm.author = '';
this.editForm.read = [];
},
editBook(book){
Object.assign(this.editForm, book)
},
onSubmit(){
this.$refs.addBookModal.hide()
let read = false
if (this.addBookForm.read[0]) read = true
const payload = {
id: this.addBookForm.id,
title: this.addBookForm.title,
author: this.addBookForm.author,
read,// property shorthand
@ -118,15 +168,49 @@ export default {
// this is an alternative way to call actions
// this.$store.dispatch('POST_BOOK', payload)
this.POST_BOOK(payload)
this.message = 'book added!'
.then((response) => {
this.message = "Book added!"
this.alertVariant = "success"
this.showMessage = true
})
.catch(error => {
this.message = "Error in adding book"
this.alertVariant = "danger"
this.showMessage = true
})
this.initForm()
},
onReset() {
//alternatively capture the event and evt.preventDefault()
this.$refs.addBookModal.hide()
this.initForm()
},
onSubmitUpdate() {
this.$refs.editBookModal.hide()
let read = false
if (this.editForm.read[0]) read = true
const payload = {
id: this.editForm.id,
title: this.editForm.title,
author: this.editForm.author,
read,
}
this.PUT_BOOK(payload)
.then((response) => {
this.message = "Book updated"
this.alertVariant = "success"
this.showMessage = true
})
.catch(error => {
this.message = "Error in updating book"
this.alertVariant = "danger"
this.showMessage = true
})
},
onResetUpdate() {
this.$refs.editBookModal.hide()
this.initForm()
},
},
computed:{
@ -135,6 +219,13 @@ export default {
created() {
//this.$store.dispatch('
this.LOAD_BOOKS_LIST()
.then((response) => {
})
.catch(error => {
this.message = "Error in fetching book list"
this.alertVariant = "danger"
this.showMessage = true
})
}
}

@ -17,16 +17,31 @@ export default new Vuex.Store({
},
ADD_BOOK: (state, book) => {
state.books.push(book)
},
UPDATE_BOOK: (state, book) => {
for (let item of state.books) {
if (item.id == book.id) {
Object.assign(item, book)
return
}
}
throw "No book was found by that id"
},
}, //mutations
actions: {
LOAD_BOOKS_LIST({commit}) {
return new Promise((resolve, reject) => {
appService.getAllBooks().
then((data) => { commit('SET_BOOK_LIST', data.books)})
resolve()
}
appService.getAllBooks()
.then((data) => {
commit('SET_BOOK_LIST', data.books)
resolve(data)
})
.catch(error => {
reject(error)
})
}
)
},
POST_BOOK(context, book){
@ -42,5 +57,18 @@ export default new Vuex.Store({
})
})
},
PUT_BOOK(context, book){
return new Promise((resolve, reject) => {
appService.updateBook(book)
.then(data => {
context.commit('UPDATE_BOOK', book)
resolve()
})
.catch(data => {
console.log(data)
reject()
})
})
}
},//actions
})

@ -1,21 +1,25 @@
from flask import Flask, jsonify, request
from flask_cors import CORS
import uuid
# config
DEBUG = True
BOOKS = [
{
'id': uuid.uuid4().hex,
'title': 'On the Road',
'author': 'Jack Kerouac',
'read': True
},
{
'id': uuid.uuid4().hex,
'title': 'Harry Potter and the Philosopher\'s Stone',
'author': 'J. K. Rowling',
'read': False
},
{
'id': uuid.uuid4().hex,
'title': 'Green Eggs and Ham',
'author': 'Dr. Seuss',
'read': True
@ -23,6 +27,14 @@ BOOKS = [
]
def remove_book(book_id):
for book in BOOKS:
if book['id'] == book_id:
BOOKS.remove(book)
return True
return False
# app init
app = Flask(__name__)
app.config.from_object(__name__)
@ -43,6 +55,7 @@ def all_books():
if request.method == 'POST':
post_data = request.get_json()
BOOKS.append({
'id': uuid.uuid4().hex,
'title': post_data.get('title'),
'author': post_data.get('author'),
'read': post_data.get('read')
@ -53,5 +66,27 @@ def all_books():
return jsonify(response_object)
@app.route('/books/<book_id>', methods=['PUT'])
def single_book(book_id):
response_object = {'status': 'success'}
if request.method == 'PUT':
post_data = request.get_json()
# print(post_data)
#remove_book(book_id)
# BOOKS.append({
# 'id': uuid.uuid4().hex,
# 'title': post_data.get('title'),
# 'author': post_data.get('author'),
# 'read': post_data.get('read')
# })
for item in BOOKS:
print(item['id'])
if item['id'] == post_data['id']:
item.update(**post_data)
break
response_object['message'] = 'Book updated!'
return jsonify(response_object)
if __name__ == '__main__':
app.run()

Loading…
Cancel
Save