Advertisement
mahmoudabdelkhalk

dbhelper

Aug 14th, 2018
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class DBHelper {
  2.     /**
  3.      * Database URL.
  4.      * Change this to restaurants.json file location on your server.
  5.      */
  6.     static get DATABASE_URL() {
  7.         const port = 1337; // Change this to your server port
  8.         return `http://localhost:${port}/restaurants`;
  9.     }
  10.  
  11.     /**
  12.      * Fetch all restaurants.
  13.      */
  14.     static fetchRestaurants(callback) {
  15.         let fetchURL = DBHelper.DATABASE_URL;;
  16.         fetch(fetchURL, { method: "GET" })
  17.             .then(response => { response.json()
  18.                     .then(restaurants => {
  19.                         if (restaurants.length) {
  20.                             // Get all neighborhoods from all restaurants
  21.                             const neighborhoods = restaurants.map((v, i) => restaurants[i].neighborhood);
  22.                             // Remove duplicates from neighborhoods
  23.                             var fetchedNeighborhoods = neighborhoods.filter((v, i) => neighborhoods.indexOf(v) == i);
  24.                             // Get all cuisines from all restaurants
  25.                             const cuisines = restaurants.map((v, i) => restaurants[i].cuisine_type);
  26.                             // Remove duplicates from cuisines
  27.                             fetchedCuisines = cuisines.filter((v, i) => cuisines.indexOf(v) == i);
  28.                         }
  29.                         callback(null, restaurants);
  30.                     });
  31.             }).catch(error => {
  32.                 callback(`Request failed. Returned ${error}`, null);
  33.             });
  34.     }
  35.     /**
  36.      * Fetch a restaurant by its ID.
  37.      */
  38.     static fetchRestaurantById(id, callback) {
  39.         // fetch all restaurants with proper error handling.
  40.         DBHelper.fetchRestaurants((error, restaurants) => {
  41.             if (error) {
  42.                 callback(error, null);
  43.             } else {
  44.                 //const restaurant = restaurants.find(r => r.id == id);
  45.                 const restaurant = restaurants;
  46.                 if (restaurant) {
  47.                     // Got the restaurant
  48.                     callback(null, restaurant);
  49.                 } else {
  50.                     // Restaurant does not exist in the database
  51.                     callback("Restaurant does not exist", null);
  52.                 }
  53.             }
  54.         }, id);
  55.     }
  56.     static fetchRestaurantReviewsById(id, callback) {
  57.         // Fetch all reviews for the specific restaurant
  58.         const fetchURL = DBHelper.DATABASE_REVIEWS_URL + "/?restaurant_id=" + id;
  59.         fetch(fetchURL, {
  60.             method: "GET"
  61.         }).then(response => {
  62.             if (!response.clone().ok && !response.clone().redirected) {
  63.                 throw "No reviews available";
  64.             }
  65.             response.json().then(result => {
  66.                 callback(null, result);
  67.             })
  68.         }).catch(error => callback(error, null));
  69.     }
  70.     /**
  71.      * Fetch restaurants by a cuisine type with proper error handling.
  72.      */
  73.     static fetchRestaurantByCuisine(cuisine, callback) {
  74.         // Fetch all restaurants  with proper error handling
  75.         DBHelper.fetchRestaurants((error, restaurants) => {
  76.             if (error) {
  77.                 callback(error, null);
  78.             } else {
  79.                 // Filter restaurants to have only given cuisine type
  80.                 const results = restaurants.filter(r => r.cuisine_type === cuisine);
  81.                 callback(null, results);
  82.             }
  83.         });
  84.     }
  85.     /**
  86.      * Fetch restaurants by a neighborhood with proper error handling.
  87.      */
  88.     static fetchRestaurantByNeighborhood(neighborhood, callback) {
  89.         // Fetch all restaurants
  90.         DBHelper.fetchRestaurants((error, restaurants) => {
  91.             if (error) {
  92.                 callback(error, null);
  93.             } else {
  94.                 // Filter restaurants to have only given neighborhood
  95.                 const results = restaurants.filter(r => r.neighborhood === neighborhood);
  96.                 callback(null, results);
  97.             }
  98.         });
  99.     }
  100.     /**
  101.      * Fetch restaurants by a cuisine and a neighborhood with proper error handling.
  102.      */
  103.     static fetchRestaurantByCuisineAndNeighborhood(cuisine, neighborhood, callback) {
  104.         // Fetch all restaurants
  105.         DBHelper.fetchRestaurants((error, restaurants) => {
  106.             if (error) {
  107.                 callback(error, null);
  108.             } else {
  109.                 let results = restaurants;
  110.                 if (cuisine != "all") {
  111.                     // filter by cuisine
  112.                     results = results.filter(r => r.cuisine_type == cuisine);
  113.                 }
  114.                 if (neighborhood != "all") {
  115.                     // filter by neighborhood
  116.                     results = results.filter(r => r.neighborhood == neighborhood);
  117.                 }
  118.                 callback(null, results);
  119.             }
  120.         });
  121.     }
  122.     /**
  123.      * Fetch all neighborhoods with proper error handling.
  124.      */
  125.     static fetchNeighborhoods(callback, fetchedNeighborhoods) {
  126.         if (fetchedNeighborhoods) {
  127.             callback(null, fetchedNeighborhoods);
  128.             return;
  129.         }
  130.         // Fetch all restaurants
  131.         DBHelper.fetchRestaurants((error, restaurants) => {
  132.             if (error) {
  133.                 callback(error, null);
  134.             } else {
  135.                 // Get all neighborhoods from all restaurants
  136.                 const neighborhoods = restaurants.map((v, i) => restaurants[i].neighborhood);
  137.                 // Remove duplicates from neighborhoods
  138.                 fetchedNeighborhoods = neighborhoods.filter((v, i) => neighborhoods.indexOf(v) == i);
  139.                 callback(null, fetchedNeighborhoods);
  140.             }
  141.         });
  142.     }
  143.     /**
  144.      * Fetch all cuisines with proper error handling.
  145.      */
  146.     static fetchCuisines(callback, fetchedCuisines) {
  147.         if (fetchedCuisines) {
  148.             callback(null, fetchedCuisines);
  149.             return;
  150.         }
  151.         // Fetch all restaurants
  152.         DBHelper.fetchRestaurants((error, restaurants) => {
  153.             if (error) {
  154.                 callback(error, null);
  155.             } else {
  156.                 // Get all cuisines from all restaurants
  157.                 const cuisines = restaurants.map((v, i) => restaurants[i].cuisine_type);
  158.                 // Remove duplicates from cuisines
  159.                 fetchedCuisines = cuisines.filter((v, i) => cuisines.indexOf(v) == i);
  160.                 callback(null, fetchedCuisines);
  161.             }
  162.         });
  163.     }
  164.     /**
  165.      * Restaurant page URL.
  166.      */
  167.     static urlForRestaurant(restaurant) {
  168.         return `./restaurant.html?id=${restaurant.id}`;
  169.     }
  170.     /**
  171.      * Restaurant image URL.
  172.      */
  173.     static imageUrlForRestaurant(restaurant, type) {
  174.         if (restaurant.photograph) {
  175.             return `/img/${type}/${restaurant.photograph}.jpg`;
  176.         }
  177.         return `/img/${type}/${restaurant.id}.jpg`;
  178.     }
  179.     /**
  180.      * Map marker for a restaurant.
  181.      */
  182.     static mapMarkerForRestaurant(restaurant, map) {
  183.         // https://leafletjs.com/reference-1.3.0.html#marker
  184.         const marker = new L.marker([restaurant.latlng.lat, restaurant.latlng.lng], {
  185.             title: restaurant.name,
  186.             alt: restaurant.name,
  187.             url: DBHelper.urlForRestaurant(restaurant)
  188.         })
  189.         marker.addTo(newMap);
  190.         return marker;
  191.     }
  192.     static addPendingRequestToQueue(url, method, body) {
  193.         // Open the database ad add the request details to the pending table
  194.         const dbPromise = idb.open("fm-udacity-restaurant");
  195.         dbPromise.then(db => {
  196.                 const tx = db.transaction("pending", "readwrite");
  197.                 tx.objectStore("pending").put({
  198.                     data: {
  199.                         url,
  200.                         method,
  201.                         body
  202.                     }
  203.                 })
  204.             })
  205.             .catch(error => {})
  206.             .then(DBHelper.nextPending());
  207.     }
  208.     static nextPending() {
  209.         DBHelper.attemptCommitPending(DBHelper.nextPending);
  210.     }
  211.     static attemptCommitPending(callback) {
  212.         // Iterate over the pending items until there is a network failure
  213.         let url;
  214.         let method;
  215.         let body;
  216.         //const dbPromise = idb.open("fm-udacity-restaurant");
  217.         dbPromise.then(db => {
  218.             if (!db.objectStoreNames.length) {
  219.                 console.log("DB not available");
  220.                 db.close();
  221.                 return;
  222.             }
  223.             const tx = db.transaction("pending", "readwrite");
  224.             tx
  225.                 .objectStore("pending")
  226.                 .openCursor()
  227.                 .then(cursor => {
  228.                     if (!cursor) {
  229.                         return;
  230.                     }
  231.                     const value = cursor.value;
  232.                     url = cursor.value.data.url;
  233.                     method = cursor.value.data.method;
  234.                     body = cursor.value.data.body;
  235.                     // If we don't have a parameter then we're on a bad record that should be tossed
  236.                     // and then move on
  237.                     if ((!url || !method) || (method === "POST" && !body)) {
  238.                         cursor
  239.                             .delete()
  240.                             .then(callback());
  241.                         return;
  242.                     };
  243.                     const properties = {
  244.                         body: JSON.stringify(body),
  245.                         method: method
  246.                     }
  247.                     console.log("sending post from queue: ", properties);
  248.                     fetch(url, properties)
  249.                         .then(response => {
  250.                             // If we don't get a good response then assume we're offline
  251.                             if (!response.ok && !response.redirected) {
  252.                                 return;
  253.                             }
  254.                         })
  255.                         .then(() => {
  256.                             // Success! Delete the item from the pending queue
  257.                             const deltx = db.transaction("pending", "readwrite");
  258.                             deltx
  259.                                 .objectStore("pending")
  260.                                 .openCursor()
  261.                                 .then(cursor => {
  262.                                     cursor
  263.                                         .delete()
  264.                                         .then(() => {
  265.                                             callback();
  266.                                         })
  267.                                 })
  268.                             console.log("deleted pending item from queue");
  269.                         })
  270.                 })
  271.                 .catch(error => {
  272.                     console.log("Error reading cursor");
  273.                     return;
  274.                 })
  275.         })
  276.     }
  277.     static updateCachedRestaurantData(id, updateObj) {
  278.         const dbPromise = idb.open("fm-udacity-restaurant");
  279.         // Update in the data for all restaurants first
  280.         dbPromise.then(db => {
  281.             console.log("Getting db transaction");
  282.             const tx = db.transaction("restaurants", "readwrite");
  283.             const value = tx
  284.                 .objectStore("restaurants")
  285.                 .get("-1")
  286.                 .then(value => {
  287.                     if (!value) {
  288.                         console.log("No cached data found");
  289.                         return;
  290.                     }
  291.                     const data = value.data;
  292.                     const restaurantArr = data.filter(r => r.id === id);
  293.                     const restaurantObj = restaurantArr[0];
  294.                     // Update restaurantObj with updateObj details
  295.                     if (!restaurantObj)
  296.                         return;
  297.                     const keys = Object.keys(updateObj);
  298.                     keys.forEach(k => {
  299.                         restaurantObj[k] = updateObj[k];
  300.                     })
  301.                     // Put the data back in IDB storage
  302.                     dbPromise.then(db => {
  303.                         const tx = db.transaction("restaurants", "readwrite");
  304.                         tx
  305.                             .objectStore("restaurants")
  306.                             .put({
  307.                                 id: "-1",
  308.                                 data: data
  309.                             });
  310.                         return tx.complete;
  311.                     })
  312.                 })
  313.         })
  314.         // Update the restaurant specific data
  315.         dbPromise.then(db => {
  316.             console.log("Getting db transaction");
  317.             const tx = db.transaction("restaurants", "readwrite");
  318.             const value = tx
  319.                 .objectStore("restaurants")
  320.                 .get(id + "")
  321.                 .then(value => {
  322.                     if (!value) {
  323.                         console.log("No cached data found");
  324.                         return;
  325.                     }
  326.                     const restaurantObj = value.data;
  327.                     console.log("Specific restaurant obj: ", restaurantObj);
  328.                     // Update restaurantObj with updateObj details
  329.                     if (!restaurantObj)
  330.                         return;
  331.                     const keys = Object.keys(updateObj);
  332.                     keys.forEach(k => {
  333.                         restaurantObj[k] = updateObj[k];
  334.                     })
  335.                     // Put the data back in IDB storage
  336.                     dbPromise.then(db => {
  337.                         const tx = db.transaction("restaurants", "readwrite");
  338.                         tx
  339.                             .objectStore("restaurants")
  340.                             .put({
  341.                                 id: id + "",
  342.                                 data: restaurantObj
  343.                             });
  344.                         return tx.complete;
  345.                     })
  346.                 })
  347.         })
  348.     }
  349.  
  350. }
  351. window.DBHelper = DBHelper;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement