*
* @requires app.core
* @requires app.welcome
- * @requires app.rest
+ * @requires app.cars
*
* @description
* # app
/* Feature areas */
'app.welcome',
- 'app.rest'
+ 'app.cars'
]);
}());
--- /dev/null
+(function () {
+ 'use strict';
+
+ angular
+ .module('app.cars')
+ .controller('CarsErrorModal', CarsErrorModal);
+
+ /**
+ * @ngdoc controller
+ * @name app.cars.controller:CarsErrorModal
+ *
+ * @description
+ * Controller for error modal in cars application.
+ */
+ /* @ngInject */
+ function CarsErrorModal($modalInstance, cars) {
+ var vm = this;
+
+ vm.cars = cars;
+ vm.selected = {
+ car: vm.cars[0]
+ };
+
+ vm.ok = function () {
+ var isAllowedEvent = $modalInstance.close(vm.selected.car);
+ console.log('close: broadcasted event to the modal scope before the modal closes. ' +
+ 'Was it allowed?' + isAllowedEvent);
+ };
+
+ vm.cancel = function () {
+ var isAllowedEvent = $modalInstance.dismiss('cancel');
+ console.log('dismiss: broadcasted event to the modal scope before the modal closes. ' +
+ 'Was it allowed?' + isAllowedEvent);
+ };
+ }
+
+})();
--- /dev/null
+<!DOCTYPE html>
+<div class="modal-header">
+ <h3 class="modal-title">Cars error modal!</h3>
+</div>
+<div class="modal-body">
+ <ul>
+ Something went wrong!!!
+ </ul>
+ <ul>
+ <li ng-repeat="car in vm.cars">
+ <a href="#" ng-click="$event.preventDefault(); vm.selected.car = car">{{ car }}</a>
+ </li>
+ </ul>
+ Selected: <b>{{ vm.selected.car }}</b>
+</div>
+<div class="modal-footer">
+ <button class="btn btn-primary" type="button" ng-click="vm.ok()">OK</button>
+ <button class="btn btn-warning" type="button" ng-click="vm.cancel()">Cancel</button>
+</div>
\ No newline at end of file
--- /dev/null
+(function () {
+ 'use strict';
+
+ var prefix = '/';
+
+ angular
+ .module('app.cars')
+ .constant('API', {
+ CARS: prefix + 'api/cars',
+ CAR: prefix + 'api/cars/:carId'
+ });
+
+})();
--- /dev/null
+(function () {
+ 'use strict';
+
+ angular
+ .module('app.cars')
+ .controller('Cars', Cars);
+
+ /**
+ * @ngdoc controller
+ * @name app.cars.controller:Cars
+ *
+ * @requires $modal
+ * @requires $timeout
+ * @requires app.cars.cars
+ *
+ * <p>
+ * <br>
+ * {@link http://angular-ui.github.io/bootstrap/#/modal $modal}
+ * {@link https://docs.angularjs.org/api/ng/service/$timeout $timeout}
+ * </p>
+ *
+ * @description
+ * Cars controller.
+ */
+ /* @ngInject */
+ function Cars($modal, $timeout, cars) {
+ var vm = this;
+ vm.example = {
+ text: 'try to send data',
+ word: /^\s*\w*\s*$/,
+ singleModel: 1
+ };
+ vm.getCars = getCars;
+
+ function getCars() {
+ // ES6 way. success and error are deprecated because they are not following the ES6 way.
+ cars.getAll().then(
+ // Success
+ function (value) {
+ vm.cars = value;
+ },
+ // Error
+ function(reason) {
+ console.log('Cars controller error: ' + reason);
+ doModal('lg');
+ }
+ );
+ }
+
+ function doModal(size) {
+ var cars = ['car1', 'car2', 'car3'];
+ var modalInstance = $modal.open({
+ animation: true,
+ templateUrl: 'app/cars/cars-error-modal.html',
+ controller: 'CarsErrorModal as vm',
+ size: size,
+ backdrop: 'static',
+ keyboard: false,
+ resolve: {
+ cars: function () {
+ return cars;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (selectedItem) {
+ vm.selected = selectedItem;
+ }, function (reason) {
+ if (reason === '$uibUnscheduledDestruction') {
+ console.log('Modal\'s scope destroyed by unexpected mechanism');
+ }
+ console.log('Modal dismissed at: ' + new Date());
+ console.log('Modal dismissed reason: ' + reason);
+ });
+
+ modalInstance.opened.then(function(value) {
+ console.log('Modal opened success at: ' + new Date());
+ console.log('Modal opened success value: ' + value);
+ }, function(reason) {
+ console.log('Modal opened error at: ' + new Date());
+ console.log('Modal opened error value: ' + reason);
+ });
+
+ modalInstance.rendered.then(function(value) {
+ console.log('Modal rendered success at: ' + new Date());
+ console.log('Modal rendered success value: ' + value);
+ }, function(reason) {
+ console.log('Modal rendered error at: ' + new Date());
+ console.log('Modal rendered error value: ' + reason);
+ });
+
+ $timeout(function() {
+ console.log('closed by tiemout at: ' + new Date());
+ modalInstance.close('closed by tiemout');
+ }, 5000);
+
+ $timeout(function() {
+ console.log('dismissed by tiemout at: ' + new Date());
+ modalInstance.dismiss('dismissed by tiemout');
+ }, 10000);
+ }
+ }
+
+})();
--- /dev/null
+describe('app.cars', function() {
+ 'use strict';
+
+ var Cars;
+ var cars = {
+ getAll: function() {
+ return {};
+ }
+ };
+ var $q;
+
+ beforeEach(function() {
+ module('app.cars');
+
+ inject(function($controller, $location, _$q_) {
+ Cars = $controller('Cars', {
+ $location: $location,
+ cars: cars
+ });
+ $q = _$q_;
+ });
+ });
+
+ describe('Cars controller', function () {
+
+ it('should invoke GET all cars in service', function () {
+
+ spyOn(cars, 'getAll')
+ .and.callFake(function() {
+ var deferred = $q.defer();
+ return deferred.promise;
+ });
+
+ Cars.getCars();
+
+ expect(cars.getAll).toHaveBeenCalled();
+ });
+ });
+
+});
--- /dev/null
+<!DOCTYPE html>
+<div class="container">
+
+ <form name="myForm" ng-controller="Cars as vm">
+ <label>Single word:</label>
+ <input type="text" name="input" ng-model="vm.example.text"
+ ng-pattern="vm.example.word" required ng-trim="false">
+ <div role="alert">
+ <span class="error" ng-show="myForm.input.$error.required">
+ Required!</span>
+ <span class="error" ng-show="myForm.input.$error.pattern">
+ Single word only!</span>
+ </div>
+ <span>text = {{vm.example.text}}</span><br/>
+ <span>myForm.input.$valid = {{myForm.input.$valid}}</span><br/>
+ <span>myForm.input.$error = {{myForm.input.$error}}</span><br/>
+ <span>myForm.$valid = {{myForm.$valid}}</span><br/>
+ <span>myForm.$error.required = {{!!myForm.$error.required}}</span><br/>
+ <button type="button" class="btn btn-primary" ng-disabled="myForm.input.$invalid">
+ Single Toggle
+ </button>
+ <ul >
+ <li ng-repeat="car in vm.cars"> {{ car.content }} </li>
+ </ul>
+ <button type="button" class="btn btn-primary" ng-disabled="myForm.input.$invalid"
+ ng-click="vm.getCars()">
+ Get cars
+ </button>
+ </form>
+</div>
\ No newline at end of file
--- /dev/null
+(function() {
+ 'use strict';
+
+ /**
+ * @ngdoc overview
+ * @name app.cars
+ *
+ * @requires app.core
+ *
+ * @description
+ * # app.cars
+ *
+ * ## Module cars.
+ * Module in charge of sending REST requests.
+ */
+ angular.module('app.cars', [
+ 'app.core'
+ ]);
+
+})();
--- /dev/null
+(function() {
+ 'use strict';
+
+ angular
+ .module('app.cars')
+ .config(configure);
+
+ /**
+ * @ngdoc service
+ * @name app.cars.configure
+ *
+ * @requires $stateProvider
+ * @requires $urlRouterProvider
+ *
+ * <p>
+ * <br>
+ * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider $stateProvider} <br>
+ * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.router.$urlRouterProvider $urlRouterProvider}
+ * </p>
+ *
+ *
+ * @description
+ * Router configuration for cars application.
+ */
+ /* @ngInject */
+ function configure($stateProvider, $urlRouterProvider) {
+ var state = 'cars';
+ var config = {
+ abstract: false,
+ url: '/cars',
+ templateUrl: 'app/cars/cars.html'
+ };
+
+ $urlRouterProvider.otherwise(state);
+ $stateProvider.state(state, config);
+ }
+}());
--- /dev/null
+describe('app.cars', function() {
+ 'use strict';
+
+ describe('state', function() {
+ var view = {
+ cars: 'app/cars/cars.html'
+ };
+ var $state;
+
+ beforeEach(function() {
+ module('app.cars');
+
+ inject(function(_$state_) {
+ $state = _$state_;
+ });
+ });
+
+ it('should map /cars route to cars View template', function() {
+ expect($state.get('cars').templateUrl). toEqual(view.cars);
+ });
+
+ });
+
+});
--- /dev/null
+(function () {
+ 'use strict';
+
+ angular
+ .module('app.cars')
+ .factory('cars', cars);
+
+ /**
+ * @ngdoc service
+ * @name app.cars.cars
+ *
+ * @requires $http
+ * @requires $q
+ *
+ * <p>
+ * <br>
+ * {@link https://docs.angularjs.org/api/ng/service/$http $http} <br>
+ * {@link https://docs.angularjs.org/api/ng/service/$q $q}
+ * </p>
+ *
+ * @description
+ * cars service.
+ */
+ /* @ngInject */
+ function cars($http, $q, API) {
+ return {
+ getAll: getAll
+ };
+
+ /**
+ * @ngdoc method
+ * @name getAll
+ * @methodOf app.cars.cars
+ *
+ * @description
+ * Get cars from API REST.
+ */
+ function getAll() {
+ return $http.get(API.CARS)
+ // a) Using success and error from promise. They are deprecated because it is not the ES6 way. DO NOT USE THEM!
+ // https://github.com/angular/angular.js/commit/a8f7e9cfde82ed7eaba3a868d8acafdf57f2d76f
+ // .success(successAlternative)
+ // .error(errorAlternative)
+ // b) Using then from promise. ES6 way.
+ .then(success, error, notify)
+ // Pattern: either use error callback or catch but not both of them as the same time!!!!
+ // .catch(failed)
+ .finally(finalizer);
+
+ function success(resp) {
+ /**
+ * resp, object containing:
+ *
+ * config: Object
+ * headers: Object
+ * Accept: "application/json, text/plain, *!/!*"
+ * method: "GET"
+ * paramSerializer: ngParamSerializer(params)
+ * transformRequest: Array[1]
+ * transformResponse: Array[1]
+ * url: "/api/cars"
+ * data: Array[3]
+ * 0: Object
+ * content: "Car: 1"
+ * id: 4
+ * 1: Object
+ * content: "Car: 2"
+ * id: 5
+ * length: 2
+ * headers: function(name)
+ * status: 200
+ * statusText: "OK"
+ */
+
+ // In this way, then next chained promise will use just its success callback. :(
+ // What means, promise will be resolved immediately!!! If it is what you want go ahead.
+ // return resp.data;
+
+ // Better return promise. :) Two options:
+
+ // a) ES6 way (it doesn't have notify :(
+ // return $q(function(resolve) {
+ // resolve(resp.data);
+ // })
+
+ // b) The CommonJS Promise way. It has the notify method (which I am not using here)
+ var deferred = $q.defer();
+ deferred.resolve(resp.data);
+ return deferred.promise;
+ }
+
+ // DO NOT USE IT!!! This way has been deprecated because it is not the ES6 way.
+ function successAlternative(data, status, headers, config) {
+ console.log('XHR SuccessAlternative for getAll. SuccessAlternative, data: ' + data);
+ console.log('XHR SuccessAlternative for getAll. SuccessAlternative, status: ' + status);
+ console.log('XHR SuccessAlternative for getAll. SuccessAlternative, headers (it is a function): ' + headers);
+ console.log('XHR SuccessAlternative for getAll. SuccessAlternative, config: ' + config);
+ }
+
+ function error(reason) {
+ /**
+ * resp, object containing:
+ *
+ * config: Object
+ * headers: Object
+ * Accept: "application/json, text/plain, *!/!*"
+ * method: "GET"
+ * paramSerializer: ngParamSerializer(params)
+ * transformRequest: Array[1]
+ * transformResponse: Array[1]
+ * url: "/api/cars"
+ * data: "Error: connect ECONNREFUSED"
+ * headers: function(name)
+ * status: 500
+ * statusText: "Internal Server Error"
+ */
+ console.log('XHR Error for getAll. Error: ' + reason.data);
+
+ // In this way, then next chained promise will use just its success callback. :(
+ // What means, promise will be resolved immediately!!! If it is what you want go ahead.
+ // return reason.data;
+
+ // Better return promise. :) Three options:
+
+ // a) ES6 way, it doesn't have notify :(
+ // return $q(function(resolve, reject) {
+ // reject(reason.data);
+ // })
+
+ // b) The CommonJS Promise way. It has the notify method (which I am not using here)
+ // var deferred = $q.defer();
+ // deferred.reject(reason.data);
+ // return deferred.promise;
+
+ // c) The CommonJS Promise way. The same as b) but with less code :)
+ return $q.reject(reason.data);
+ }
+
+ // DO NOT USE IT!!! This way has been deprecated because it is not the ES6 way.
+ function errorAlternative(data, status, headers, config) {
+ console.log('XHR ErrorAlternative for getAll. ErrorAlternative, data: ' + data);
+ console.log('XHR ErrorAlternative for getAll. ErrorAlternative, status: ' + status);
+ console.log('XHR ErrorAlternative for getAll. ErrorAlternative, headers (it is a function): ' + headers);
+ console.log('XHR ErrorAlternative for getAll. ErrorAlternative, config: ' + config);
+ }
+
+ function notify(notification) {
+ console.log('XHR Notification for getAll. Notification: ' + notification);
+ }
+
+ function failed(reason) {
+ /**
+ * reason, object containing (the same as resp object for error function):
+ *
+ * config: Object
+ * headers: Object
+ * Accept: "application/json, text/plain, *!/!*"
+ * method: "GET"
+ * paramSerializer: ngParamSerializer(params)
+ * transformRequest: Array[1]
+ * transformResponse: Array[1]
+ * url: "/api/cars"
+ * data: "Error: connect ECONNREFUSED"
+ * headers: function(name)
+ * status: 500
+ * statusText: "Internal Server Error"
+ */
+ console.log('XHR Failed for getAll. Reason: ' + reason);
+
+ // In this way, then next chained promise will use just its success callback.
+ // What means, promise will be resolved immediately!!! If it is what you want go ahead.
+ // return reason.data;
+
+ // Better return promise. :) Three options:
+
+ // a) ES6 way, it doesn't have notify :(
+ // return $q(function(resolve, reject) {
+ // reject(reason.data);
+ // })
+
+ // b) The CommonJS Promise way. It has the notify method (which I am not using here)
+ // var deferred = $q.defer();
+ // deferred.reject(reason.data);
+ // return deferred.promise;
+
+ // c) The CommonJS Promise way. The same as b) but with less code :)
+ return $q.reject(reason.data);
+
+ }
+
+ function finalizer() {
+ // This callback doesn't have any input parameter :(
+ console.log('XHR Finalizer for getAll.');
+ }
+ }
+ }
+
+}());
--- /dev/null
+describe('app.cars', function() {
+ 'use strict';
+
+ var $httpBackend;
+ var $log;
+ var cars;
+ var API;
+
+ beforeEach(function() {
+ module('app.cars');
+
+ inject(function(_$httpBackend_, _$log_, _cars_, _API_) {
+ $httpBackend = _$httpBackend_;
+ $log = _$log_;
+ cars = _cars_;
+ API = _API_;
+ });
+ });
+
+ describe('cars service', function () {
+
+ it('should invoke GET all cars', function () {
+ $httpBackend.expectGET(API.CARS).respond({});
+
+ cars.getAll();
+
+ $httpBackend.flush();
+ });
+ });
+
+ afterEach(function() {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+});
+++ /dev/null
-(function () {
- 'use strict';
-
- angular
- .module('app.rest')
- .controller('RestErrorModal', RestErrorModal);
-
- /**
- * @ngdoc controller
- * @name app.rest.controller:RestErrorModal
- *
- * @description
- * Controller for error modal in rest application.
- */
- /* @ngInject */
- function RestErrorModal($modalInstance, cars) {
- var vm = this;
-
- vm.cars = cars;
- vm.selected = {
- car: vm.cars[0]
- };
-
- vm.ok = function () {
- var isAllowedEvent = $modalInstance.close(vm.selected.car);
- console.log('close: broadcasted event to the modal scope before the modal closes. ' +
- 'Was it allowed?' + isAllowedEvent);
- };
-
- vm.cancel = function () {
- var isAllowedEvent = $modalInstance.dismiss('cancel');
- console.log('dismiss: broadcasted event to the modal scope before the modal closes. ' +
- 'Was it allowed?' + isAllowedEvent);
- };
- }
-
-})();
+++ /dev/null
-<!DOCTYPE html>
-<div class="modal-header">
- <h3 class="modal-title">REST error modal!</h3>
-</div>
-<div class="modal-body">
- <ul>
- Something went wrong!!!
- </ul>
- <ul>
- <li ng-repeat="car in vm.cars">
- <a href="#" ng-click="$event.preventDefault(); vm.selected.car = car">{{ car }}</a>
- </li>
- </ul>
- Selected: <b>{{ vm.selected.car }}</b>
-</div>
-<div class="modal-footer">
- <button class="btn btn-primary" type="button" ng-click="vm.ok()">OK</button>
- <button class="btn btn-warning" type="button" ng-click="vm.cancel()">Cancel</button>
-</div>
\ No newline at end of file
+++ /dev/null
-(function () {
- 'use strict';
-
- var prefix = '/';
-
- angular
- .module('app.rest')
- .constant('API', {
- CARS: prefix + 'api/cars',
- CAR: prefix + 'api/cars/:carId'
- });
-
-})();
+++ /dev/null
-(function () {
- 'use strict';
-
- angular
- .module('app.rest')
- .controller('Rest', Rest);
-
- /**
- * @ngdoc controller
- * @name app.rest.controller:Rest
- *
- * @requires $modal
- * @requires $timeout
- * @requires app.rest.rest
- *
- * <p>
- * <br>
- * {@link http://angular-ui.github.io/bootstrap/#/modal $modal}
- * {@link https://docs.angularjs.org/api/ng/service/$timeout $timeout}
- * </p>
- *
- * @description
- * Rest controller.
- */
- /* @ngInject */
- function Rest($modal, $timeout, rest) {
- var vm = this;
- vm.example = {
- text: 'try to send data',
- word: /^\s*\w*\s*$/,
- singleModel: 1
- };
- vm.getCars = getCars;
-
- function getCars() {
- // ES6 way. success and error are deprecated because they are not following the ES6 way.
- rest.getAll().then(
- // Success
- function (value) {
- vm.cars = value;
- },
- // Error
- function(reason) {
- console.log('Rest controller error: ' + reason);
- doModal('lg');
- }
- );
- }
-
- function doModal(size) {
- var cars = ['car1', 'car2', 'car3'];
- var modalInstance = $modal.open({
- animation: true,
- templateUrl: 'app/rest/rest-error-modal.html',
- controller: 'RestErrorModal as vm',
- size: size,
- backdrop: 'static',
- keyboard: false,
- resolve: {
- cars: function () {
- return cars;
- }
- }
- });
-
- modalInstance.result.then(function (selectedItem) {
- vm.selected = selectedItem;
- }, function (reason) {
- if (reason === '$uibUnscheduledDestruction') {
- console.log('Modal\'s scope destroyed by unexpected mechanism');
- }
- console.log('Modal dismissed at: ' + new Date());
- console.log('Modal dismissed reason: ' + reason);
- });
-
- modalInstance.opened.then(function(value) {
- console.log('Modal opened success at: ' + new Date());
- console.log('Modal opened success value: ' + value);
- }, function(reason) {
- console.log('Modal opened error at: ' + new Date());
- console.log('Modal opened error value: ' + reason);
- });
-
- modalInstance.rendered.then(function(value) {
- console.log('Modal rendered success at: ' + new Date());
- console.log('Modal rendered success value: ' + value);
- }, function(reason) {
- console.log('Modal rendered error at: ' + new Date());
- console.log('Modal rendered error value: ' + reason);
- });
-
- $timeout(modalInstance.close('closed by tiemout'), 5000);
-
- $timeout(modalInstance.dismiss('closed by tiemout'), 10000);
- }
- }
-
-})();
+++ /dev/null
-describe('app.rest', function() {
- 'use strict';
-
- var Rest;
- var cars = {
- getAll: function() {
- return {};
- }
- };
- var $q;
-
- beforeEach(function() {
- module('app.rest');
-
- inject(function($controller, $location, _$q_) {
- Rest = $controller('Rest', {
- $location: $location,
- cars: cars
- });
- $q = _$q_;
- });
- });
-
- describe('Rest controller', function () {
-
- it('should invoke GET all cars in service', function () {
-
- spyOn(cars, 'getAll')
- .and.callFake(function() {
- var deferred = $q.defer();
- return deferred.promise;
- });
-
- Rest.getCars();
-
- expect(cars.getAll).toHaveBeenCalled();
- });
- });
-
-});
+++ /dev/null
-<!DOCTYPE html>
-<div class="container">
-
- <form name="myForm" ng-controller="Rest as vm">
- <label>Single word:</label>
- <input type="text" name="input" ng-model="vm.example.text"
- ng-pattern="vm.example.word" required ng-trim="false">
- <div role="alert">
- <span class="error" ng-show="myForm.input.$error.required">
- Required!</span>
- <span class="error" ng-show="myForm.input.$error.pattern">
- Single word only!</span>
- </div>
- <span>text = {{vm.example.text}}</span><br/>
- <span>myForm.input.$valid = {{myForm.input.$valid}}</span><br/>
- <span>myForm.input.$error = {{myForm.input.$error}}</span><br/>
- <span>myForm.$valid = {{myForm.$valid}}</span><br/>
- <span>myForm.$error.required = {{!!myForm.$error.required}}</span><br/>
- <button type="button" class="btn btn-primary" ng-disabled="myForm.input.$invalid">
- Single Toggle
- </button>
- <ul >
- <li ng-repeat="car in vm.cars"> {{ car.content }} </li>
- </ul>
- <button type="button" class="btn btn-primary" ng-disabled="myForm.input.$invalid"
- ng-click="vm.getCars()">
- Get cars
- </button>
- </form>
-</div>
\ No newline at end of file
+++ /dev/null
-(function() {
- 'use strict';
-
- /**
- * @ngdoc overview
- * @name app.rest
- *
- * @requires app.core
- *
- * @description
- * # app.rest
- *
- * ## Module rest.
- * Module in charge of sending REST requests.
- */
- angular.module('app.rest', [
- 'app.core'
- ]);
-
-})();
+++ /dev/null
-(function() {
- 'use strict';
-
- angular
- .module('app.rest')
- .config(configure);
-
- /**
- * @ngdoc service
- * @name app.rest.configure
- *
- * @requires $stateProvider
- * @requires $urlRouterProvider
- *
- * <p>
- * <br>
- * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider $stateProvider} <br>
- * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.router.$urlRouterProvider $urlRouterProvider}
- * </p>
- *
- *
- * @description
- * Router configuration for rest application.
- */
- /* @ngInject */
- function configure($stateProvider, $urlRouterProvider) {
- var state = 'rest';
- var config = {
- abstract: false,
- url: '/rest',
- templateUrl: 'app/rest/rest.html'
- };
-
- $urlRouterProvider.otherwise(state);
- $stateProvider.state(state, config);
- }
-}());
+++ /dev/null
-describe('app.rest', function() {
- 'use strict';
-
- describe('state', function() {
- var view = {
- rest: 'app/rest/rest.html'
- };
- var $state;
-
- beforeEach(function() {
- module('app.rest');
-
- inject(function(_$state_) {
- $state = _$state_;
- });
- });
-
- it('should map /rest route to rest View template', function() {
- expect($state.get('rest').templateUrl). toEqual(view.rest);
- });
-
- });
-
-});
+++ /dev/null
-(function () {
- 'use strict';
-
- angular
- .module('app.rest')
- .factory('rest', rest);
-
- /**
- * @ngdoc service
- * @name app.rest.rest
- *
- * @requires $http
- * @requires $q
- *
- * <p>
- * <br>
- * {@link https://docs.angularjs.org/api/ng/service/$http $http} <br>
- * {@link https://docs.angularjs.org/api/ng/service/$q $q}
- * </p>
- *
- * @description
- * Rest service.
- */
- /* @ngInject */
- function rest($http, $q, API) {
- return {
- getAll: getAll
- };
-
- /**
- * @ngdoc method
- * @name getAll
- * @methodOf app.rest.rest
- *
- * @description
- * Get cars from API REST.
- */
- function getAll() {
- return $http.get(API.CARS)
- // a) Using success and error from promise. They are deprecated because it is not the ES6 way. DO NOT USE THEM!
- // https://github.com/angular/angular.js/commit/a8f7e9cfde82ed7eaba3a868d8acafdf57f2d76f
- // .success(successAlternative)
- // .error(errorAlternative)
- // b) Using then from promise. ES6 way.
- .then(success, error, notify)
- // Pattern: either use error callback or catch but not both of them as the same time!!!!
- // .catch(failed)
- .finally(finalizer);
-
- function success(resp) {
- /**
- * resp, object containing:
- *
- * config: Object
- * headers: Object
- * Accept: "application/json, text/plain, *!/!*"
- * method: "GET"
- * paramSerializer: ngParamSerializer(params)
- * transformRequest: Array[1]
- * transformResponse: Array[1]
- * url: "/api/cars"
- * data: Array[3]
- * 0: Object
- * content: "Car: 1"
- * id: 4
- * 1: Object
- * content: "Car: 2"
- * id: 5
- * length: 2
- * headers: function(name)
- * status: 200
- * statusText: "OK"
- */
-
- // In this way, then next chained promise will use just its success callback. :(
- // What means, promise will be resolved immediately!!! If it is what you want go ahead.
- // return resp.data;
-
- // Better return promise. :) Two options:
-
- // a) ES6 way (it doesn't have notify :(
- // return $q(function(resolve) {
- // resolve(resp.data);
- // })
-
- // b) The CommonJS Promise way. It has the notify method (which I am not using here)
- var deferred = $q.defer();
- deferred.resolve(resp.data);
- return deferred.promise;
- }
-
- // DO NOT USE IT!!! This way has been deprecated because it is not the ES6 way.
- function successAlternative(data, status, headers, config) {
- console.log('XHR SuccessAlternative for getAll. SuccessAlternative, data: ' + data);
- console.log('XHR SuccessAlternative for getAll. SuccessAlternative, status: ' + status);
- console.log('XHR SuccessAlternative for getAll. SuccessAlternative, headers (it is a function): ' + headers);
- console.log('XHR SuccessAlternative for getAll. SuccessAlternative, config: ' + config);
- }
-
- function error(reason) {
- /**
- * resp, object containing:
- *
- * config: Object
- * headers: Object
- * Accept: "application/json, text/plain, *!/!*"
- * method: "GET"
- * paramSerializer: ngParamSerializer(params)
- * transformRequest: Array[1]
- * transformResponse: Array[1]
- * url: "/api/cars"
- * data: "Error: connect ECONNREFUSED"
- * headers: function(name)
- * status: 500
- * statusText: "Internal Server Error"
- */
- console.log('XHR Error for getAll. Error: ' + reason.data);
-
- // In this way, then next chained promise will use just its success callback. :(
- // What means, promise will be resolved immediately!!! If it is what you want go ahead.
- // return reason.data;
-
- // Better return promise. :) Three options:
-
- // a) ES6 way, it doesn't have notify :(
- // return $q(function(resolve, reject) {
- // reject(reason.data);
- // })
-
- // b) The CommonJS Promise way. It has the notify method (which I am not using here)
- // var deferred = $q.defer();
- // deferred.reject(reason.data);
- // return deferred.promise;
-
- // c) The CommonJS Promise way. The same as b) but with less code :)
- return $q.reject(reason.data);
- }
-
- // DO NOT USE IT!!! This way has been deprecated because it is not the ES6 way.
- function errorAlternative(data, status, headers, config) {
- console.log('XHR ErrorAlternative for getAll. ErrorAlternative, data: ' + data);
- console.log('XHR ErrorAlternative for getAll. ErrorAlternative, status: ' + status);
- console.log('XHR ErrorAlternative for getAll. ErrorAlternative, headers (it is a function): ' + headers);
- console.log('XHR ErrorAlternative for getAll. ErrorAlternative, config: ' + config);
- }
-
- function notify(notification) {
- console.log('XHR Notification for getAll. Notification: ' + notification);
- }
-
- function failed(reason) {
- /**
- * reason, object containing (the same as resp object for error function):
- *
- * config: Object
- * headers: Object
- * Accept: "application/json, text/plain, *!/!*"
- * method: "GET"
- * paramSerializer: ngParamSerializer(params)
- * transformRequest: Array[1]
- * transformResponse: Array[1]
- * url: "/api/cars"
- * data: "Error: connect ECONNREFUSED"
- * headers: function(name)
- * status: 500
- * statusText: "Internal Server Error"
- */
- console.log('XHR Failed for getAll. Reason: ' + reason);
-
- // In this way, then next chained promise will use just its success callback.
- // What means, promise will be resolved immediately!!! If it is what you want go ahead.
- // return reason.data;
-
- // Better return promise. :) Three options:
-
- // a) ES6 way, it doesn't have notify :(
- // return $q(function(resolve, reject) {
- // reject(reason.data);
- // })
-
- // b) The CommonJS Promise way. It has the notify method (which I am not using here)
- // var deferred = $q.defer();
- // deferred.reject(reason.data);
- // return deferred.promise;
-
- // c) The CommonJS Promise way. The same as b) but with less code :)
- return $q.reject(reason.data);
-
- }
-
- function finalizer() {
- // This callback doesn't have any input parameter :(
- console.log('XHR Finalizer for getAll.');
- }
- }
- }
-
-}());
+++ /dev/null
-describe('app.rest', function() {
- 'use strict';
-
- var $httpBackend;
- var $log;
- var cars;
- var API;
-
- beforeEach(function() {
- module('app.rest');
-
- inject(function(_$httpBackend_, _$log_, _cars_, _API_) {
- $httpBackend = _$httpBackend_;
- $log = _$log_;
- cars = _cars_;
- API = _API_;
- });
- });
-
- describe('cars service', function () {
-
- it('should invoke GET all cars', function () {
- $httpBackend.expectGET(API.CARS).respond({});
-
- cars.getAll();
-
- $httpBackend.flush();
- });
- });
-
- afterEach(function() {
- $httpBackend.verifyNoOutstandingExpectation();
- $httpBackend.verifyNoOutstandingRequest();
- });
-
-});
<script src="/src/showcase/app/welcome/welcome.module.js"></script>
<script src="/src/showcase/app/welcome/welcome.route.js"></script>
<script src="/src/showcase/app/welcome/welcome.controller.js"></script>
- <script src="/src/showcase/app/rest/rest.module.js"></script>
- <script src="/src/showcase/app/rest/rest.service.js"></script>
- <script src="/src/showcase/app/rest/rest.route.js"></script>
- <script src="/src/showcase/app/rest/rest.controller.js"></script>
- <script src="/src/showcase/app/rest/rest.constants.js"></script>
- <script src="/src/showcase/app/rest/rest-error-modal.controller.js"></script>
+ <script src="/src/showcase/app/cars/cars.module.js"></script>
+ <script src="/src/showcase/app/cars/cars.service.js"></script>
+ <script src="/src/showcase/app/cars/cars.route.js"></script>
+ <script src="/src/showcase/app/cars/cars.controller.js"></script>
+ <script src="/src/showcase/app/cars/cars.constants.js"></script>
+ <script src="/src/showcase/app/cars/cars-error-modal.controller.js"></script>
<script src="/src/showcase/app/core/core.module.js"></script>
<script src="/src/showcase/app/app.module.js"></script>
<!-- endinject -->