diff --git a/app/scripts/controllers/brand.js b/app/scripts/controllers/brand.js index a3e53412..500e5e1e 100644 --- a/app/scripts/controllers/brand.js +++ b/app/scripts/controllers/brand.js @@ -19,7 +19,6 @@ angular.module('endslaverynowApp') $scope.relatedCategories = []; dataRepositoryFactory.ready( - $scope, function () { var dataRepository = dataRepositoryFactory.getDataRepository(); // Get brand information diff --git a/app/scripts/controllers/categories.js b/app/scripts/controllers/categories.js index 700c30c6..3637318c 100644 --- a/app/scripts/controllers/categories.js +++ b/app/scripts/controllers/categories.js @@ -16,7 +16,6 @@ angular.module('endslaverynowApp') $scope.allCategories = []; dataRepositoryFactory.ready( - $scope, function () { $scope.allCategories = dataRepositoryFactory.getDataRepository().getCategories(); diff --git a/app/scripts/controllers/category.js b/app/scripts/controllers/category.js index d002af3b..b5418fdc 100644 --- a/app/scripts/controllers/category.js +++ b/app/scripts/controllers/category.js @@ -20,7 +20,6 @@ angular.module('endslaverynowApp') $scope.relatedCategories = []; dataRepositoryFactory.ready( - $scope, function () { var dataRepository = dataRepositoryFactory.getDataRepository(); // Get brand information diff --git a/app/scripts/controllers/certifications.js b/app/scripts/controllers/certifications.js index 097fb5b5..48a6754d 100644 --- a/app/scripts/controllers/certifications.js +++ b/app/scripts/controllers/certifications.js @@ -13,7 +13,6 @@ angular.module('endslaverynowApp') 'dataRepositoryFactory', function ($scope, dataRepositoryFactory) { dataRepositoryFactory.ready( - $scope, function () { // Get certification information $scope.certifications = dataRepositoryFactory.getDataRepository().getCertifications(); diff --git a/app/scripts/controllers/editBrand.js b/app/scripts/controllers/editBrand.js index 426918e6..ae87aacf 100644 --- a/app/scripts/controllers/editBrand.js +++ b/app/scripts/controllers/editBrand.js @@ -30,7 +30,6 @@ angular.module('endslaverynowApp').controller('EditBrandCtrl', [ $scope.Image = null; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); diff --git a/app/scripts/controllers/editBrands.js b/app/scripts/controllers/editBrands.js index 0718f65d..d4973ceb 100644 --- a/app/scripts/controllers/editBrands.js +++ b/app/scripts/controllers/editBrands.js @@ -9,16 +9,15 @@ */ angular.module('endslaverynowApp').controller('EditBrandsCtrl', [ '$scope', - '$window', + '$state', 'dataRepositoryFactory', - function ($scope, $window, dataRepositoryFactory) { + function ($scope, $state, dataRepositoryFactory) { $scope.loaded = false; $scope.dataRepository = null; $scope.brands = []; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); $scope.brands = $scope.dataRepository.getBrands(); @@ -38,8 +37,8 @@ angular.module('endslaverynowApp').controller('EditBrandsCtrl', [ $scope.dataRepository.deleteBrand( brand, function () { - // @TODO: We need to find a more efficient/nicer way of refreshing the list of brands. - $window.location.reload(); + window.alert('Brand has been deleted'); + $state.reload(); } ); }; diff --git a/app/scripts/controllers/editCategories.js b/app/scripts/controllers/editCategories.js index 7aeebad9..269a657c 100644 --- a/app/scripts/controllers/editCategories.js +++ b/app/scripts/controllers/editCategories.js @@ -9,9 +9,9 @@ */ angular.module('endslaverynowApp').controller('EditCategoriesCtrl', [ '$scope', - '$window', + '$state', 'dataRepositoryFactory', - function ($scope, $window, dataRepositoryFactory) { + function ($scope, $state, dataRepositoryFactory) { $scope.dataRepository = null; $scope.loaded = false; @@ -19,7 +19,6 @@ angular.module('endslaverynowApp').controller('EditCategoriesCtrl', [ $scope.categories = []; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); $scope.categories = $scope.dataRepository.getCategories(); @@ -39,8 +38,8 @@ angular.module('endslaverynowApp').controller('EditCategoriesCtrl', [ $scope.dataRepository.deleteCategory( category, function () { - // @TODO: We need to find a more efficient/nicer way of refreshing the list of brands. - $window.location.reload(); + window.alert('Category has been deleted'); + $state.reload(); } ); }; diff --git a/app/scripts/controllers/editCategory.js b/app/scripts/controllers/editCategory.js index da832184..6a116dbf 100644 --- a/app/scripts/controllers/editCategory.js +++ b/app/scripts/controllers/editCategory.js @@ -25,7 +25,6 @@ angular.module('endslaverynowApp').controller('EditCategoryCtrl', [ $scope.Image = null; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); diff --git a/app/scripts/controllers/editProduct.js b/app/scripts/controllers/editProduct.js index 7883f9eb..1d99f60e 100644 --- a/app/scripts/controllers/editProduct.js +++ b/app/scripts/controllers/editProduct.js @@ -25,7 +25,6 @@ angular.module('endslaverynowApp').controller('EditProductCtrl', [ $scope.Image = null; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); diff --git a/app/scripts/controllers/editProducts.js b/app/scripts/controllers/editProducts.js index eedf370a..abec63d0 100644 --- a/app/scripts/controllers/editProducts.js +++ b/app/scripts/controllers/editProducts.js @@ -9,9 +9,9 @@ */ angular.module('endslaverynowApp').controller('EditProductsCtrl', [ '$scope', - '$window', + '$state', 'dataRepositoryFactory', - function ($scope, $window, dataRepositoryFactory) { + function ($scope, $state, dataRepositoryFactory) { $scope.dataRepository = null; $scope.loaded = false; @@ -19,7 +19,6 @@ angular.module('endslaverynowApp').controller('EditProductsCtrl', [ $scope.products = []; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); $scope.products = $scope.dataRepository.getProducts(); @@ -57,8 +56,8 @@ angular.module('endslaverynowApp').controller('EditProductsCtrl', [ $scope.dataRepository.deleteProduct( product, function () { - // @TODO: We need to find a more efficient/nicer way of refreshing the list of brands. - $window.location.reload(); + window.alert('Product has been deleted'); + $state.reload(); } ); }; diff --git a/app/scripts/controllers/formAdd.js b/app/scripts/controllers/formAdd.js index bcd066a7..8873b2ae 100644 --- a/app/scripts/controllers/formAdd.js +++ b/app/scripts/controllers/formAdd.js @@ -11,10 +11,10 @@ angular.module('endslaverynowApp') .controller('FormAddCtrl', [ '$stateParams', '$scope', - '$window', + '$state', 'Upload', 'dataRepositoryFactory', - function ($stateParams, $scope, $window, Upload, dataRepositoryFactory) { + function ($stateParams, $scope, $state, Upload, dataRepositoryFactory) { $scope.brandId = $stateParams.id; $scope.loaded = false; @@ -104,7 +104,6 @@ angular.module('endslaverynowApp') }; dataRepositoryFactory.ready( - $scope, function () { var dataRepository = dataRepositoryFactory.getDataRepository(); $scope.categories = alphabetizeCollection(dataRepository.getCategories().filter(Boolean)); @@ -238,6 +237,7 @@ angular.module('endslaverynowApp') }; $scope.reloadPage = function () { - $window.location.reload(); + // This reloads the page (controller) and the data (not that any is visible) without reloading the entire app. + $state.reload(); }; }]); diff --git a/app/scripts/controllers/main.js b/app/scripts/controllers/main.js index 5dc468af..700b1a63 100644 --- a/app/scripts/controllers/main.js +++ b/app/scripts/controllers/main.js @@ -15,7 +15,6 @@ angular.module('endslaverynowApp') $scope.categories = []; dataRepositoryFactory.ready( - $scope, function () { $scope.categories = dataRepositoryFactory.getDataRepository().getTopLevelCategories(); diff --git a/app/scripts/controllers/product.js b/app/scripts/controllers/product.js index 141e5e14..339645ac 100644 --- a/app/scripts/controllers/product.js +++ b/app/scripts/controllers/product.js @@ -18,7 +18,6 @@ angular.module('endslaverynowApp') $scope.dataRepository = null; dataRepositoryFactory.ready( - $scope, function () { $scope.dataRepository = dataRepositoryFactory.getDataRepository(); diff --git a/app/scripts/services/DataRepository.js b/app/scripts/services/DataRepository.js index 19f5ed69..a31b86ba 100644 --- a/app/scripts/services/DataRepository.js +++ b/app/scripts/services/DataRepository.js @@ -3,20 +3,21 @@ /** * This class handles the interface between the raw source data and the application. It exposes the raw data in * the form of models (and arrays of models). The "persist" methods write the data back to the data property in - * the container that's passed in. The container is actually a scope object (controller) as it's the only way we - * can bind to the raw data. + * the container that's passed in. * - * @param dataContainer - * @param syncObject * @param recordSets * @constructor */ -var DataRepository = function (dataContainer, syncObject, recordSets) { - this.syncObject = syncObject; +var DataRepository = function (recordSets) { this.recordSets = recordSets; this.brands = []; this.categories = []; this.products = []; + const collectionNames = { + brands: 'brands', + categories: 'categories', + products: 'products' + }; this.init = function init() { this.brands = []; @@ -25,24 +26,24 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { this.certifications = []; // @TODO: There doesn't seem to be any certification data, so we don't try to load it. var self = this; - if (this.syncObject.hasOwnProperty('brands')) { - this.syncObject.brands.forEach( + if (this.recordSets.hasOwnProperty(collectionNames.brands)) { + this.recordSets.brands.forEach( function (brand) { self.brands.push(new Brand(brand)); } ); } - if (this.syncObject.hasOwnProperty('categories')) { - this.syncObject.categories.forEach( + if (this.recordSets.hasOwnProperty(collectionNames.categories)) { + this.recordSets.categories.forEach( function (category) { self.categories.push(new Category(category)); } ); } - if (this.syncObject.hasOwnProperty('products')) { - this.syncObject.products.forEach( + if (this.recordSets.hasOwnProperty(collectionNames.products)) { + this.recordSets.products.forEach( function (product) { self.products.push(new Product(product)); } @@ -178,8 +179,24 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { return null; }; - this.save = function save(successMsg, callback) { - this.syncObject.$save().then( + this.insert = function insert(collectionName, record, successMsg, callback) { + this.recordSets[collectionName].$add(record).then( + function () { + if (successMsg) { + window.alert(successMsg); + } + if (callback) { + callback(); + } + }, + function (error) { + window.alert('Error: ' + error.toString()); + } + ); + }; + + this.update = function update(collectionName, recordIndex, successMsg, callback) { + this.recordSets[collectionName].$save(recordIndex).then( function () { if (successMsg) { window.alert(successMsg); @@ -194,6 +211,35 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { ); }; + this.populateRecordFromBrandModel = function populateRecordFromBrandModel(brandRecord, brand) { + brandRecord.name = brand.getName(); + brandRecord.description = brand.getDescription(); + brandRecord.categories = brand.getCategoryIdAsCsl(); + brandRecord.image = brand.getImage(); + brandRecord.ranking = brand.getRanking(); + // brandRecord.brandUrl = brand.getBrandURL(); // @TODO: There does not seem to be a URL property in the data. + }; + + this.populateRecordFromCategoryModel = function populateRecordFromCategoryModel(categoryRecord, category) { + categoryRecord.description = category.getDescription(); + categoryRecord.image = category.getImage(); + categoryRecord.name = category.getName(); + categoryRecord.parentCategoryId = category.getParentCategoryId(); + }; + + this.populateRecordFromProductModel = function populateRecordFromProductModel(productRecord, product) { + productRecord.brandId = product.getBrandId(); + productRecord.categoryId = product.getCategoryId(); + productRecord.description = product.getDescription(); + productRecord.id = product.getId(); + productRecord.image = product.getImage(); + productRecord.name = product.getName(); + productRecord.parentCategoryId = product.getParentCategoryId(); + productRecord.purchaseURlClicks = product.getPurchaseUrlClicks(); + productRecord.purchaseUrl = product.getPurchaseUrl(); + // productRecord.$$hashKey = product.$$hashKey(); @TODO: Do we save this? When does it change? + }; + /** * Save the given brand back to the data store. * @@ -202,19 +248,31 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { * @param callback {Function|null} */ this.persistBrand = function persistBrand(brand, successMsg, callback) { - if (!brand.hasId()) { - // This is an insert. + if (brand.hasId()) { + + // This is an update. + // Determine the index of the record in the array from the model's id. + var brandIndex = this.determineIndexFromBrandModel(brand); + // Create a reference to the object in the array. + var brandSource = this.recordSets.brands[brandIndex]; + // Overwrite the record with the values from the model. + this.populateRecordFromBrandModel(brandSource, brand); + // Save the record back to the store. + this.update(collectionNames.brands, brandIndex, successMsg, callback); + + } else { + + // This is an insert. Generate a new id and start a new object. brand.setId(this.generateNextBrandId()); - dataContainer.data.brands[brand.getId()] = {id: brand.getId()}; + var newBrand = { + id: brand.getId() + }; + // Populate the record with the values from the model. + this.populateRecordFromBrandModel(newBrand, brand); + // Create the record in the store. + this.insert(collectionNames.brands, newBrand, successMsg, callback); + } - var brandSource = dataContainer.data.brands[brand.getId()]; - brandSource.name = brand.getName(); - brandSource.description = brand.getDescription(); - brandSource.categories = brand.getCategoryIdAsCsl(); - brandSource.image = brand.getImage(); - brandSource.ranking = brand.getRanking(); - // brandSource.brandUrl = brand.getBrandURL(); // @TODO: There does not seem to be a URL property in the data. - this.save(successMsg, callback); }; /** @@ -225,17 +283,31 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { * @param callback {Function|null} */ this.persistCategory = function persistCategory(category, successMsg, callback) { - if (!category.hasId()) { - // This is an insert. + if (category.hasId()) { + + // This is an update. + // Determine the index of the record in the array from the model's id. + var categoryIndex = this.determineIndexFromCategoryModel(category); + // Create a reference to the object in the array. + var categorySource = this.recordSets.categories[categoryIndex]; + // Overwrite the record with the values from the model. + this.populateRecordFromCategoryModel(categorySource, category); + // Save the record back to the store. + this.update(collectionNames.categories, categoryIndex, successMsg, callback); + + } else { + + // This is an insert. Generate a new id and start a new object. category.setId(this.generateNextCategoryId()); - dataContainer.data.categories[category.getId()] = {id: category.getId()}; + var newCategory = { + id: category.getId() + }; + // Populate the record with the values from the model. + this.populateRecordFromCategoryModel(newCategory, category); + // Create the record in the store. + this.insert(collectionNames.categories, newCategory, successMsg, callback); + } - var categorySource = dataContainer.data.categories[category.getId()]; - categorySource.description = category.getDescription(); - categorySource.image = category.getImage(); - categorySource.name = category.getName(); - categorySource.parentCategoryId = category.getParentCategoryId(); - this.save(successMsg, callback); }; /** @@ -246,49 +318,99 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { * @param callback */ this.persistProduct = function persistProduct(product, successMsg, callback) { - if (!product.hasId()) { - // This is an insert. + if (product.hasId()) { + + // This is an update. + // Determine the index of the record in the array from the model's id. + var productIndex = this.determineIndexFromProductModel(product); + // Create a reference to the object in the array. + var productSource = this.recordSets.products[productIndex]; + // Overwrite the record with the values from the model. + this.populateRecordFromProductModel(productSource, product); + // Save the record back to the store. + this.update(collectionNames.products, productIndex, successMsg, callback); + + } else { + + // This is an insert. Generate a new id and start a new object. product.setId(this.generateNextProductId()); - dataContainer.data.products[product.getId()] = {id: product.getId()}; + var newProduct = { + id: product.getId() + }; + // Populate the record with the values from the model. + this.populateRecordFromProductModel(newProduct, product); + // Create the record in the store. + this.insert(collectionNames.products, newProduct, successMsg, callback); + } - var productSource = dataContainer.data.products[product.getId()]; - productSource.brandId = product.getBrandId(); - productSource.categoryId = product.getCategoryId(); - productSource.description = product.getDescription(); - productSource.id = product.getId(); - productSource.image = product.getImage(); - productSource.name = product.getName(); - productSource.parentCategoryId = product.getParentCategoryId(); - productSource.purchaseURlClicks = product.getPurchaseUrlClicks(); - productSource.purchaseUrl = product.getPurchaseUrl(); - // productSource.$$hashKey = product.$$hashKey(); @TODO: Do we save this? When does it change? - this.save(successMsg, callback); }; this.generateNextBrandId = function generateNextBrandId() { - var id = Math.max(1, dataContainer.data.brands.length); - while (dataContainer.data.brands[id] !== undefined) { - ++id; - } + var id = 0; + this.recordSets.brands.forEach(function (brand) { + id = Math.max(id, brand.id); + }); + ++id; + return id; }; this.generateNextCategoryId = function generateNextCategoryId() { - var id = Math.max(1, dataContainer.data.categories.length); - while (dataContainer.data.categories[id] !== undefined) { - ++id; - } + var id = 0; + this.recordSets.categories.forEach(function (category) { + id = Math.max(id, category.id); + }); + ++id; + return id; }; this.generateNextProductId = function generateNextProductId() { - var id = Math.max(1, dataContainer.data.products.length); - while (dataContainer.data.products[id] !== undefined) { - ++id; - } + var id = 0; + this.recordSets.products.forEach(function (product) { + id = Math.max(id, product.id); + }); + ++id; + return id; }; + this.determineIndexFromBrandModel = function determineIndexFromBrandModel(brandModel) { + // Determine the index of the firebase array, using the brand model's id. + var brandIndex = null; + this.recordSets.brands.forEach(function(brand, index) { + if (brand.id === brandModel.getId()) { + brandIndex = index; + } + }); + + return brandIndex; + }; + + this.determineIndexFromCategoryModel = function determineIndexFromCategoryModel(categoryModel) { + // Determine the index of the firebase array, using the category model's id. + var categoryIndex = null; + this.recordSets.categories.forEach(function(category, index) { + if (category.id === categoryModel.getId()) { + categoryIndex = index; + } + }); + + return categoryIndex; + }; + + this.determineIndexFromProductModel = function determineIndexFromProductModel(productModel) { + // Determine the index of the firebase array, using the product model's id. + var productIndex = null; + this.recordSets.products.forEach(function(product, index) { + if (product.id === productModel.getId()) { + productIndex = index; + } + }); + + return productIndex; + }; + /** * @TODO: Presumably we should update any references to this brand (or prevent delete if anything references it)? * @TODO: And what about uploaded images? Should they be deleted? What if something else is referencing it? @@ -298,12 +420,7 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { */ this.deleteBrand = function deleteBrand(brandModel, callback) { // Determine the index of the firebase array, using the brand model's id. - var indexToDelete = null; - this.recordSets.brands.forEach(function(brand, index) { - if (brand.id === brandModel.getId()) { - indexToDelete = index; - } - }); + var indexToDelete = this.determineIndexFromBrandModel(brandModel); if (indexToDelete !== null) { // We found it, so delete it. If the delete was successful, run the callback function. this.recordSets.brands.$remove(indexToDelete).then(function () { @@ -324,12 +441,7 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { */ this.deleteCategory = function deleteCategory(categoryModel, callback) { // Determine the index of the firebase array, using the category model's id. - var indexToDelete = null; - this.recordSets.categories.forEach(function(category, index) { - if (category.id === categoryModel.getId()) { - indexToDelete = index; - } - }); + var indexToDelete = this.determineIndexFromCategoryModel(categoryModel); if (indexToDelete !== null) { // We found it, so delete it. If the delete was successful, run the callback function. this.recordSets.categories.$remove(indexToDelete).then(function () { @@ -350,12 +462,7 @@ var DataRepository = function (dataContainer, syncObject, recordSets) { */ this.deleteProduct = function deleteProduct(productModel, callback) { // Determine the index of the firebase array, using the product model's id. - var indexToDelete = null; - this.recordSets.products.forEach(function(product, index) { - if (product.id === productModel.getId()) { - indexToDelete = index; - } - }); + var indexToDelete = this.determineIndexFromProductModel(productModel); if (indexToDelete !== null) { // We found it, so delete it. If the delete was successful, run the callback function. this.recordSets.products.$remove(indexToDelete).then(function () { diff --git a/app/scripts/services/DataRepositoryFactory.js b/app/scripts/services/DataRepositoryFactory.js index 9a6b2ea1..14a9bb1d 100644 --- a/app/scripts/services/DataRepositoryFactory.js +++ b/app/scripts/services/DataRepositoryFactory.js @@ -12,41 +12,17 @@ var DataRepositoryFactory = function ($firebaseObject, $firebaseArray) { this.dataRepository = null; this.storageRepository = new StorageRepository(firebase); - this.$scope = null; - this.bind = function bind() { - if (this.$scope) { - this.syncObject.$bindTo(this.$scope, 'data'); - } - }; - /** - * This method binds the sync object to the "data" property of the scope object. Unfortunately, you can only - * bind to a controller ($scope), otherwise we could just use the repository class or whatever. - * It then waits until the firebase object has been initialised, and then constructs a new data repository + * This method waits until the firebase object has been initialised, and then constructs a new data repository * with it, passing in the scope, and then passes that in to the callback function provided by the calling code. * - * @param $scope * @param callback */ - this.ready = function ready($scope, callback) { + this.ready = function ready(callback) { var self = this; - self.$scope = $scope; - self.bind(); - this.syncObject.$loaded().then(function () { - // @TODO: I'm not sure if this block is needed, or what it's trying to do, because it always seems - // @TODO: to fire as soon as the controller loads. - self.syncObject.$save().then( - function () { - console.log('Done'); // true - }, - function (error) { - console.log('Error:', error); - } - ); - - self.dataRepository = new DataRepository($scope, self.syncObject, self.recordSets); + self.dataRepository = new DataRepository(self.recordSets); // @TODO: We should probably check that "callback" is defined and is a function. callback(); }); diff --git a/app/scripts/services/PersistService.js b/app/scripts/services/PersistService.js index cad95c85..a81fa51e 100644 --- a/app/scripts/services/PersistService.js +++ b/app/scripts/services/PersistService.js @@ -21,7 +21,6 @@ var PersistService = function (dataRepositoryFactory, dataRepository, storageRep // Build the process that will persist the brand (mainly so we don't have to duplicate fairly complex code). var self = this; var doPersist = function doPersist() { - dataRepositoryFactory.bind(); self.dataRepository.persistBrand(localBrand, message, callback); }; @@ -45,7 +44,6 @@ var PersistService = function (dataRepositoryFactory, dataRepository, storageRep // Build the process that will persist the category (mainly so we don't have to duplicate fairly complex code). var self = this; var doPersist = function doPersist() { - dataRepositoryFactory.bind(); self.dataRepository.persistCategory(localCategory, message, callback); }; @@ -69,7 +67,6 @@ var PersistService = function (dataRepositoryFactory, dataRepository, storageRep // Build the process that will persist the product (mainly so we don't have to duplicate fairly complex code). var self = this; var doPersist = function doPersist() { - dataRepositoryFactory.bind(); self.dataRepository.persistProduct(localProduct, message, callback); };