I've spent a few hours trying to debug this with no real breakthroughs. My console.logs correctly output the load order.
- app
- factory
- controller
I'm annotating my dependencies (even though I'm not minifying at the moment).
Is there anything obviously wrong here that I am missing?
error
app
(function () {
'use strict';
console.log("running app");
var app = angular.module('InventoryProductApp', []).config(function ($logProvider) {
$logProvider.debugEnabled(true);
});
angular.element(document).ready(function () {
var app = document.getElementById('InventoryProductApp');
angular.bootstrap(angular.element(app), ['InventoryProductApp']);
});
})();
controller
(function () {
'use strict';
angular.module('InventoryProductApp').controller("LocationsController", ['$scope', '$log', 'LocationsFactory'
, function ($scope, $http, $log, LocationsFactory) {
console.log("running controller");
$scope.locations = null;
$scope.loading = false;
//private methods -------------------------------------------------------------------------------------------------------------------------------------------------------------
var fetchLocationData = function (inventoryId) {
$scope.loading = true;
console.log(LocationsFactory);
var promise = LocationsFactory.getLocationData(inventoryId);
promise.then(function (data) {
$scope.loading = false;
if (data.success) {
$scope.locations = data.locations;
}
else
{
$log.error('There was an error getting location data');
}
}, function (data) {
$scope.loading = false;
$log.error('There was an error getting location data');
});
}
//end private methods ---------------------------------------------------------------------------------------------------------------------------------------------------------
//public methods --------------------------------------------------------------------------------------------------------------------------------------------------------------
var init = function (inventoryId) {
console.log('inventoryId', inventoryId);
fetchLocationData(inventoryId);
}
//end public methods ----------------------------------------------------------------------------------------------------------------------------------------------------------
init(inventoryId); // inventoryId is found in the partialView _inventoryLocationDistribution
}]);
})();
factory
(function () {
'use strict';
angular.module('InventoryProductApp').factory('LocationsFactory', ['$http', '$q', '$log', function ($http, $q, $log) {
console.log("running factory");
return {
getLocationData: function (inventoryId) {
var def = $q.defer();
$http.get('/butthead', {
params: {
inventoryId: inventoryId
}
}).then(function (response) {
def.resolve({
success: true,
locations: data.locations
});
}, function (response) {
$log.error('failed to fetch data', response);
def.resolve({
success: false,
redirect: response.redirect
});
});
return def.promise;
}
}
}]);
})();
script load order
<script src="~/theme/modern/assets/global/plugins/angularjs/angular.min.js"></script>
<script src="~/App/Inventory/Product/ProductApp.js"></script>
<script src="~/App/Inventory/Product/LocationsFactory.js"></script>
<script src="~/App/Inventory/Product/LocationsController.js"></script>
In your controller:
angular.module('InventoryProductApp').controller("LocationsController",
['$scope', '$log', 'LocationsFactory', function ($scope, $http, $log, LocationsFactory) {
You're missing '$http' in your dependency injections, which means the LocationsFactory argument isn't filled at all.
Related
I have data in one controller and now I want to share it with another but both controller has different modules. I have used $rootscope but it didn't work. I have used service it also didn't work. link here Service
Is there any other way to do. I have spent one week for this please help me.
toolbar.controler
(function ()
{
'use strict';
angular
.module('app.toolbar')
.controller('ToolbarController', ToolbarController);
function ToolbarController($rootScope, $mdSidenav, msNavFoldService, $translate, $mdToast, $location, $localStorage, $http, $scope)
{
var vm = this;
vm.name = $localStorage.name;
vm.userId = $localStorage._id;
vm.readNotifications = function(notifId){
$http({
url: 'http://192.168.2.8:7200/api/readNotification',
method: 'POST',
data: {notificationId: notifId, userId: vm.userId}
}).then(function(res){
vm.rslt = res.data.result1;
console.log(vm.rslt);
vm.refresh();
$location.path('/sharedwishlistdetails');
}, function(error){
alert(error.data);
})
}
}
})();
The data stored here in vm.reslt.
toolbar.module.js
(function ()
{
'use strict';
angular
.module('app.toolbar', [])
.config(config);
/** #ngInject */
function config($stateProvider, $translatePartialLoaderProvider)
{
$translatePartialLoaderProvider.addPart('app/toolbar');
}
})();
Now I want that result for this controller.
sharedwishlistdetails.controller.js
(function ()
{
'use strict';
angular
.module('app.sharedwishlistdetails')
.controller('SharedWishlistDetailsController', SharedWishlistDetailsController);
/** #ngInject */
//NotificationsController.$inject = ['$http', '$location'];
function SharedWishlistDetailsController($http, $location, $localStorage, $rootScope, $scope)
{
var vm = this;
vm.uid = $localStorage._id;
}
})();
shareddata.service.js
(function ()
{
'use strict';
angular
.module('app.core')
.factory('shareData', shareDataService);
/** #ngInject */
function shareDataService($resource,$http) {
var shareData = {};
return shareData;
}
})();
write a service in 'app.toolbar' module
angular.module('app.toolbar').service('ServiceA', function() {
this.getValue = function() {
return this.myValue;
};
this.setValue = function(newValue) {
this.myValue = newValue;
}
});
In your toolbarController , inject ServiceA and set data -
vm.readNotifications = function(notifId){
$http({
url: 'http://192.168.2.8:7200/api/readNotification',
method: 'POST',
data: {notificationId: notifId, userId: vm.userId}
}).then(function(res){
vm.rslt = res.data.result1;
ServiceA.setValue(vm.rslt);
console.log(vm.rslt);
vm.refresh();
$location.path('/sharedwishlistdetails');
}, function(error){
alert(error.data);
})
}
Now write another service for 'app.sharedwishlistdetails' module -
angular.module('app.sharedwishlistdetails',['app.toolbar']).service('ServiceB', function(ServiceA) {
this.getValue = function() {
return ServiceA.getValue();
};
this.setValue = function() {
ServiceA.setValue('New value');
}
});
Now inject ServiceB in your SharedWishlistDetailsController controller and access data -
var sharedData = ServiceB.getValue();
How could $rootScope failed in your code it would be appreciated if you paste your code: never mind here is an example that will help you out:
All applications have a $rootScope which is the scope created on the HTML element that contains the ng-app directive.
The rootScope is available in the entire application.If a variable has the same name in both the current scope and in the rootScope, the application use the one in the current scope.
angular.module('myApp', [])
.run(function($rootScope) {
$rootScope.test = new Date();
})
.controller('myCtrl', function($scope, $rootScope) {
$scope.change = function() {
$scope.test = new Date();
};
$scope.getOrig = function() {
return $rootScope.test;
};
})
.controller('myCtrl2', function($scope, $rootScope) {
$scope.change = function() {
$scope.test = new Date();
};
$scope.changeRs = function() {
$rootScope.test = new Date();
};
$scope.getOrig = function() {
return $rootScope.test;
};
});
I'm testing the communication of angular and SQLite. I need to get the ID and NAME of the selected company from database when the User access the page. I'm using the ion-autcomplete to select the company in the CRUD page.
Service: sqlite.js
(function () {
'use strict';
angular
.module('Test')
.service('$sqliteService', $sqliteService);
$sqliteService.$inject = ['$q', '$cordovaSQLite'];
function $sqliteService($q, $cordovaSQLite) {
var self = this;
var _db;
self.db = function () {
if (!_db) {
if (window.sqlitePlugin !== undefined) {
_db = window.sqlitePlugin.openDatabase({ name: "my.db", location: 2, createFromLocation: 1 });
} else {
// For debugging in the browser
_db = window.openDatabase("my.db", "1", "Database", 200000);
}
}
return _db;
};
self.getFirstItem = function (query, parameters) {
var deferred = $q.defer();
self.executeSql(query, parameters).then(function (res) {
if (res.rows.length > 0)
return deferred.resolve(res.rows.item(0));
else
return deferred.reject("There aren't items matching");
}, function (err) {
return deferred.reject(err);
});
return deferred.promise;
};
}
})();
Factory: CompanyService.js
(function () {
'use strict';
angular
.module('Test')
.factory('CompanyService', CompanyService);
CompanyService.$inject = ['$q', '$sqliteService'];
function CompanyService($q, $sqliteService) {
return {
getId: function (Id) {
var query = "Select * FROM Company WHERE ID = ?";
var values = [Id];
return $q.when($sqliteService.getFirstItem(query, values));
}
};
}
})();
Controller: CompanyController.js
(function() {
'use strict';
angular
.module('Test')
.controller('CompanyEditController', CompanyEditController);
CompanyEditController.$inject = ['$scope', '$q', '$stateParams', '$state', '$cordovaCamera', '$cordovaImagePicker', '$ionicPopup', 'CompanyService'];
function OcorrenciaEditController($scope, $q, $stateParams , $state, $cordovaCamera, $cordovaImagePicker, $ionicPopup, CompanyService) {
var vm = $scope;
vm.modelToItemMethod = function (modelValue) {
var d = $q.defer();
CompanyService.getId(modelValue)
.then(function(data) {
console.log('My first promise succeeded', JSON.stringify(data));
$q.resolve(data);
}, function(error) {
console.log('My first promise failed', error.message);
});
return d.promise;
};
})();
Company.html
<input ion-autocomplete ng-model="company.IdCompany" type="text" name="fieldEmpresa" placeholder="Empresa" readonly="readonly" class="ion-autocomplete" autocomplete="off" max-selected-items="1" required
item-value-key="Id"
item-view-value-key="CompanyName"
items-method="getTestItems(query)"
cancel-label="Cancel"
items-removed-method="itemsRemoved()"
loader-icon="spinner"
external-model="company"
model-to-item-method="modelToItemMethod(modelValue)"/>
I don't undestand why I need to use de "$q.defer" inside the controller if i'm using inside de Factory and Service. If I don't use, controller can't return the value to ion-aucomplete. Am i missing something? Or the code is right?
You are binding this method to auto complete; as ajax call is asynchronous, you gotta return a primise. Thats the reason why you ended up using $q.defer.
If you dont want to use $q, then instead of using $q.defer , you can just do return CompanyService.getId(modalValue); in your VM.modelToItemMethod which inturn returns a deferred object.
I'm having an issue correctly getting a data service to work as I try to follow the Angular Style Guide (https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#data-services)
I'm sure it's something obvious to the more experienced but I can't get the data set to assign properly to the vm.items outside of the
Data Service
(function() {
'use strict';
angular
.module('portfolioApp')
.factory('portfolioService', portfolioService);
portfolioService.$inject = ['$http', 'logger'];
function portfolioService($http, logger) {
return {
getPortfolioData: getPortfolioData,
};
function getPortfolioData() {
return $http.get('./assets/portfolio/portfolioItems.json')
.then(getPortfolioDataComplete)
.catch(getPortfolioDataFail);
function getPortfolioDataComplete(response) {
return response.data;
}
function getPortfolioDataFail(error) {
logger.error('XHR Failed for getPortfolioData.' + error.data);
}
}
}
}());
Controller
.controller('portfolioController', ['$scope', '$http', '$stateParams', 'logger', 'portfolioService', function($scope, $http, $stateParams, logger, portfolioService) {
var vm = this;
vm.items = [];
activate();
function activate() {
return getData().then(function() {
logger.info('Activate the portfolio view');
});
}
function getData() {
return portfolioService.getPortfolioData()
.then(function(data) {
vm.items = data;
return vm.items;
});
}
console.log("test")
console.log(vm.items);
console.log("test")
}])
Your getData function is a promise, so it's run asynchronously. Your console.log are called before the end of the promise so the vm.items is still empty.
Try to put the log in the then callback.
I try to call an method of civilitiyController in CustomerController. So, with my search I have found the event's manager to call method but I don't success to return the result from CivilityController to CustomerController.
I already tried this:
1/
civilitiesController :
$scope.$on("getListCivilities", function(event, args){
$scope.civilities = getCivilitiesList();
});
customersController :
$scope.$broadcast("getListCivilities");
console.dir($scope.civilities) // after run civilities = undefined
2/CivilitiesController:
$scope.$on("getListCivilities" , function(event, args){
var list = getCivilitiesList();
return list;
});
CustomersController :
$scope.civilities = $scope.$broadcast("getListCivilities");
console.dir($scope.civilities); //display var of broadcast
3/ Edit:
After first answer, I tried this :
civilities controller :
function getCivilitiesList()
{
var reqGetCivilities = $http({ url: 'api/Civilities/Get' });
reqGetCivilities.success(function(data){
$scope.civilities = data;
$scope.$broadcast("getListCivilities", { list: $scope.civilities });
return data;
});
}
getCivilitiesList();
customersController :
function test()
{
$scope.$on("getListCivilities", function (event, args) {
$scope.civilities = args.list;
console.log('test0');
console.dir($scope.civilities);
});
}
test();
$scope.$on is never executed and I don't see why.
I hope someone can help me.
check this plunker
app.controller('Controller1', function($scope) {
$scope.name = 'World';
$scope.$on('ValueUpdated', function(event, args) {
$scope.name = args.currentValue;
});
});
app.controller('Controller2', ['$rootScope', '$scope', function($rootScope, $scope) {
$scope.myData = "type here";
$scope.broadCast = function() {
$rootScope.$broadcast('ValueUpdated', {
currentValue: $scope.myData
});
}
I used broadcast, but you can do this with services and watchers too.
I guess below should work :
function CivilitiesController($scope)
{
$scope.$on('someEvent', function(event, args) {});
// another controller or even directive
}
function CustomersController($scope)
{
$scope.$emit('someEvent', args);
}
JSFiddle (for more details) : http://jsfiddle.net/nikdtu/moo89kaw/
Ahmet Zeytindalı, this is my entire CivilitiesController :
(function () {
'use strict';
'use strict';
angular
.module('LSapp')
.controller('CivilitiesCtrl', CivilitiesCtrl)
CivilitiesCtrl.$inject = ['$scope', '$http', '$rootScope'];
function CivilitiesCtrl($scope, $http, $rootScope) {
function getCivilitiesList()
{
var reqGetCivilities = $http({ url: 'api/Civilities/Get' });
reqGetCivilities.success(function(data){
$scope.civilities = data;
});
}
getCivilitiesList();
function getList()
{
$rootScope.$broadcast("getListCivilities", { list: $scope.civilities });
}
getList();
}
})();
And the method to retreive list:
(function () {
'use strict';
angular
.module('LSapp')
.controller('CustomersCtrl', CustomersCtrl)
CustomersCtrl.$inject = ['$scope', '$http', '$location', '$modal', '$window', '$compile','$cookies', '$state','locker','$q','$timeout', '$rootScope'];
function CustomersCtrl($scope, $http, $location, $modal, $window, $compile, $cookies, $state, locker, $q, $timeout) {
//some code
function test()
{
$scope.$on("getListCivilities", function (event, args) {
$scope.civilities = args.list;
console.log('$on args : ');
console.dir(args);
});
}
test();
}
});
The method $on doesn't run and if I put console.log($scope.civilities) after the method, the result is always undefined.
Here is my html code:
<div ng-controller="withAjaxCtrl">
<table datatable="" dt-options="dtOptions" dt-columns="dtColumns" class="row-border hover"></table>
</div>
Here is my controller:
(function () {
var manageBackOrdersController = function ($scope, $http, $routeParams) {
$http({
url: '/Profiles/firstJson',
method: "GET",
params: {}
}).success(function (data) {
var JSON = data;
$scope.data = JSON;
});
}
manageBackOrdersController.$inject = ['$scope', '$http', '$routeParams'];
angular.module('customersApp')
.controller('manageOrdersController', manageOrdersController);
angular.module('datatablesSampleApp', ['datatables'])
.controller('withAjaxCtrl', function ($scope, DTOptionsBuilder, DTColumnBuilder) {
$scope.dtOptions = DTOptionsBuilder.fromSource('scope.data')
.withPaginationType('full_numbers');
$scope.dtColumns = [
DTColumnBuilder.newColumn('Customer').withTitle('Customer')
];
});
}());
When I run my page I get an error saying "Error: [ng:areq] Argument 'withAjaxCtrl' is not a function, got undefined". My data is found stored in $scope.data.
Respectfully, Sameer's answer is incorrect. It took me two long arduoous days but I found the solution.
What you must keep in mind are 2 concerns:
Use DTOptionsBuilder.fromFnPromise, and
Have your promise inside your factory.
This is the correct solution:
'use strict';
WithResponsiveCtrl.$inject = ['DTOptionsBuilder', 'DTColumnBuilder', 'simpleFactory'];
angular.module('showcase.withResponsive', [])
.controller('WithResponsiveCtrl', WithResponsiveCtrl);
function WithResponsiveCtrl(DTOptionsBuilder, DTColumnBuilder, simpleFactory) {
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
return simpleFactory.getData(); }).withPaginationType('full_numbers')
// Active Responsive plugin
.withOption('responsive', true);
vm.dtColumns = [
DTColumnBuilder.newColumn('id').withTitle('ID'),
DTColumnBuilder.newColumn('firstName').withTitle('First name'),
// .notVisible() does not work in this case. Use .withClass('none') instead
DTColumnBuilder.newColumn('lastName').withTitle('Last name').withClass('none')
]; }
simpleFactory.$inject = ['$http', '$q', '$log'];
angular.module('showcase.withResponsive').factory('simpleFactory', simpleFactory);
function simpleFactory($http, $q, $log) {
return {
getData: function () {
var deferred = $q.defer();
$http.get('api/data.json')
.success(function (data) {
deferred.resolve(data);
}).error(function (msg, code) {
deferred.reject(msg);
$log.error(msg, code);
});
return deferred.promise;
}
} };