Skip to content

Commit

Permalink
refactor: fetchRestaurants
Browse files Browse the repository at this point in the history
refactor: fetchRestaurantReviews
refactor: fetchRestaurantReviews
fix: Update restaurants in IDB when toggleFavorite
  • Loading branch information
mauricewipf committed Apr 24, 2018
1 parent cde984d commit d0722c9
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 120 deletions.
9 changes: 5 additions & 4 deletions README.md
Expand Up @@ -26,12 +26,13 @@ This app is created as part of the Udacity Nanodegree "Mobile Web Specialist".
1. First this repository.
2. Clone this repository to your desktop.
3. Open the root folder of the repository in a terminal
4. Check your python version by `python -V`
5. Start local server:
4. Run `npm i`
5. Check your python version by `python -V`
6. Start local server:
- For Python 2.x: `python -m SimpleHTTPServer 8000`
- For Python 3.x: `python3 -m http.server 8000`
6. Provide data from node server (see below)
7. Visit [http://localhost:8000](http://localhost:8000)
7. Provide data from node server (see below)
8. Visit [http://localhost:8000](http://localhost:8000)

## Data from node server

Expand Down
237 changes: 129 additions & 108 deletions js/dbhelper.js
Expand Up @@ -31,66 +31,39 @@ class DBHelper {
* Fetch all restaurants.
*/
static fetchRestaurants(callback) {
DBHelper.dbPromise.then(db => {
if (!db) {
// Fetch from network
let xhr = new XMLHttpRequest();
xhr.open('GET', `${DBHelper.DATABASE_URL}/restaurants`);
xhr.onload = () => {
if (xhr.status === 200) { // Got a success response from server!
const restaurants = JSON.parse(xhr.responseText);

this.dbPromise.then(db => {
if (!db) return;
// Put fetched restaurants into IDB
const tx = db.transaction('all-restaurants', 'readwrite');
const store = tx.objectStore('all-restaurants');
restaurants.forEach(restaurant => {
store.put(restaurant);
})
});

DBHelper.dbPromise.then(db => {
if (!db) return;
// 1. Look for restaurants in IDB
const tx = db.transaction('all-restaurants');
const store = tx.objectStore('all-restaurants');
store.getAll().then(results => {
if (results.length === 0) {
// No restaurants in IDB found
// 2. Fetch restaurants from network
fetch(`${DBHelper.DATABASE_URL}/restaurants`)
.then(response => {
return response.json();
})
.then(restaurants => {
// Restaurants fetched from network
// 3. Put fetched restaurants into IDB
const tx = db.transaction('all-restaurants', 'readwrite');
const store = tx.objectStore('all-restaurants');
restaurants.forEach(restaurant => {
store.put(restaurant);
})
callback(null, restaurants);
} else { // Oops!. Got an error from server.
const error = (`Request failed. Returned status of ${xhr.status}`);
})
.catch(error => {
// Unable to fetch from network
callback(error, null);
}
};
xhr.send();
} else {
const tx = db.transaction('all-restaurants');
const store = tx.objectStore('all-restaurants');
store.getAll().then(results => {
if (results.length === 0) {
// Fetch from network
let xhr = new XMLHttpRequest();
xhr.open('GET', `${DBHelper.DATABASE_URL}/restaurants`);
xhr.onload = () => {
if (xhr.status === 200) { // Got a success response from server!
const restaurants = JSON.parse(xhr.responseText);

this.dbPromise.then(db => {
if (!db) return;
// Put fetched restaurants into IDB
const tx = db.transaction('all-restaurants', 'readwrite');
const store = tx.objectStore('all-restaurants');
restaurants.forEach(restaurant => {
store.put(restaurant);
})
});

callback(null, restaurants);
} else { // Oops!. Got an error from server.
const error = (`Request failed. Returned status of ${xhr.status}`);
callback(error, null);
}
};
xhr.send();
} else {
callback(null, results);
}
});
}
});
} else {
// Restaurants found in IDB
callback(null, results);
}
})

});
}

Expand Down Expand Up @@ -208,60 +181,98 @@ class DBHelper {
*/
static fetchRestaurantReviews(restaurant, callback) {
DBHelper.dbPromise.then(db => {
if (true) {
// Fetch from network
fetch(`${DBHelper.DATABASE_URL}/reviews/?restaurant_id=${restaurant.id}`)
if (!db) return;
// 1. Check if there are reviews in the IDB
const tx = db.transaction('all-reviews');
const store = tx.objectStore('all-reviews');
store.getAll().then(results => {
if (results && results.length > 0) {
// Continue with reviews from IDB
callback(null, results);
} else {
// 2. If there are no reviews in the IDB, fetch reviews from the network
fetch(`${DBHelper.DATABASE_URL}/reviews/?restaurant_id=${restaurant.id}`)
.then(response => {
return response.json();
})
.then(reviews => {
this.dbPromise.then(db => {
if (!db) return;
// Put fetched reviews into IDB
// 3. Put fetched reviews into IDB
const tx = db.transaction('all-reviews', 'readwrite');
const store = tx.objectStore('all-reviews');
reviews.forEach(review => {
store.put(review);
})
});
// Continue with reviews from network
callback(null, reviews);
})
.catch(error => {
// Unable to fetch reviews from network
callback(error, null);
})
} else {
const tx = db.transaction('all-reviews');
const store = tx.objectStore('all-reviews');
store.getAll().then(results => {
if (results.length === 0) {
fetch(`${DBHelper.DATABASE_URL}/reviews/?restaurant_id=${restaurant.id}`)
.then(response => {
return response.json();
})
.then(reviews => {
this.dbPromise.then(db => {
if (!db) return;
// Put fetched reviews into IDB
const tx = db.transaction('all-reviews', 'readwrite');
const store = tx.objectStore('all-reviews');
reviews.forEach(review => {
store.put(review);
})
});
callback(null, reviews);
})
.catch(error => {
callback(error, null);
})
} else {
callback(null, results);
}
}
})
});
}

})
// static fetchRestaurantReviews(restaurant, callback) {
// DBHelper.dbPromise.then(db => {
// if (true) {
// // Fetch from network
// fetch(`${DBHelper.DATABASE_URL}/reviews/?restaurant_id=${restaurant.id}`)
// .then(response => {
// return response.json();
// })
// .then(reviews => {
// this.dbPromise.then(db => {
// if (!db) return;
// // Put fetched reviews into IDB
// const tx = db.transaction('all-reviews', 'readwrite');
// const store = tx.objectStore('all-reviews');
// reviews.forEach(review => {
// store.put(review);
// })
// });
// callback(null, reviews);
// })
// .catch(error => {
// callback(error, null);
// })
// } else {
// const tx = db.transaction('all-reviews');
// const store = tx.objectStore('all-reviews');
// store.getAll().then(results => {
// if (results.length === 0) {
// fetch(`${DBHelper.DATABASE_URL}/reviews/?restaurant_id=${restaurant.id}`)
// .then(response => {
// return response.json();
// })
// .then(reviews => {
// this.dbPromise.then(db => {
// if (!db) return;
// // Put fetched reviews into IDB
// const tx = db.transaction('all-reviews', 'readwrite');
// const store = tx.objectStore('all-reviews');
// reviews.forEach(review => {
// store.put(review);
// })
// });
// callback(null, reviews);
// })
// .catch(error => {
// callback(error, null);
// })
// } else {
// callback(null, results);
// }

}
})
}
// })

// }
// })
// }

/**
* Restaurant page URL.
Expand Down Expand Up @@ -300,7 +311,7 @@ class DBHelper {
static submitReview(data) {
console.log(data);

return fetch(`${DBHelper.DATABASE_URL}/reviews/`, {
return fetch(`${DBHelper.DATABASE_URL}/reviews`, {
body: JSON.stringify(data),
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
Expand Down Expand Up @@ -348,6 +359,7 @@ class DBHelper {

static submitOfflineReviews() {
DBHelper.dbPromise.then(db => {
if (!db) return;
const tx = db.transaction('offline-reviews');
const store = tx.objectStore('offline-reviews');
store.getAll().then(offlineReviews => {
Expand All @@ -368,24 +380,33 @@ class DBHelper {
return;
}

static toggleFavorite(restaurantId, isFavorite) {
fetch(`${DBHelper.DATABASE_URL}/restaurants/${restaurantId}/?is_favorite=${isFavorite}`, {
static toggleFavorite(restaurant, isFavorite) {
fetch(`${DBHelper.DATABASE_URL}/restaurants/${restaurant.id}/?is_favorite=${isFavorite}`, {
method: 'PUT'
})
.then(response => {
response.json()
.then(data => {
this.dbPromise.then(db => {
if (!db) return;
const tx = db.transaction('all-restaurants', 'readwrite');
const store = tx.objectStore('all-restaurants');
store.put(data)
});
return data;
})
return response.json();
})
.catch( error => {
console.log(error);
.then(data => {
DBHelper.dbPromise.then(db => {
if (!db) return;
const tx = db.transaction('all-restaurants', 'readwrite');
const store = tx.objectStore('all-restaurants');
store.put(data)
});
return data;
})
.catch(error => {
restaurant.is_favorite = isFavorite;
DBHelper.dbPromise.then(db => {
if (!db) return;
const tx = db.transaction('all-restaurants', 'readwrite');
const store = tx.objectStore('all-restaurants');
store.put(restaurant);
}).catch(error => {
console.log(error);
return;
});
});
}
}
4 changes: 2 additions & 2 deletions js/restaurant_info.js
Expand Up @@ -58,11 +58,11 @@ fillRestaurantHTML = (restaurant = self.restaurant) => {
const name = document.getElementById('restaurant-name');
name.innerHTML = restaurant.name;
name.setAttribute('tabindex', 0);

const favCheck = document.getElementById('favCheck');
favCheck.checked = restaurant.is_favorite;
favCheck.addEventListener('change', event => {
DBHelper.toggleFavorite(restaurant.id, event.target.checked);
DBHelper.toggleFavorite(restaurant, event.target.checked);
});

const address = document.getElementById('restaurant-address');
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -3,7 +3,9 @@
"version": "1.0.0",
"description": "restaurant Review App",
"main": "",
"scripts": {},
"scripts": {
"start": "python3 -m http.server 8000"
},
"author": "",
"license": "",
"private": true,
Expand Down
9 changes: 4 additions & 5 deletions sw.js
Expand Up @@ -14,7 +14,6 @@ self.addEventListener('install', function(event) {
'js/restaurant_info.js',
'js/sw_registration.js',
'node_modules/idb/lib/idb.js',
'img/',
'img/1.webp',
'img/2.webp',
'img/3.webp',
Expand Down Expand Up @@ -50,18 +49,18 @@ self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(response => {
if (response) {
console.log('Found ', event.request.url, ' in cache');
// console.log('Found in cache:', event.request.url);
return response;
}
console.log('Network request for ', event.request.url);
// console.log('Network request for ', event.request.url);
return fetch(event.request).then(networkResponse => {
if (networkResponse.status === 404) {
console.log(networkResponse.status);
// console.log(networkResponse.status);
return;
}
return caches.open(staticCacheName).then(cache => {
cache.put(event.request.url, networkResponse.clone());
console.log('Fetched and cached', event.request.url);
// console.log('Fetched and cached', event.request.url);
return networkResponse;
})
})
Expand Down

0 comments on commit d0722c9

Please sign in to comment.