Having difficulty injecting service into controller with AngularJS - javascript

I am having problems injecting ServicesData into SearchCtrl, and keep getting the following error message: Error: [$injector:unpr] Unknown provider: ServicesDataProvider <- ServicesData <- SearchCtrl. What could be the cause of this?
app.js
angular.module('starter', ['ionic', 'jett.ionic.filter.bar', 'starter.controllers'])
.state('app.playlists', {
url: '/playlists',
views: {
'menuContent': {
templateUrl: 'templates/playlists.html',
controller: 'SearchCtrl'
}
}
});
});
controller.js
angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope, $ionicModal, $timeout) {
})
.controller('SearchCtrl', ["$scope", "ServicesData", function($scope, $timeout, ServicesData, $ionicFilterBar) {
// Get list items
function getItems () {
var items = [];
for (var x = 1; x < 3; x++) {
items.push({text: 'Item number ' + x});
}
$scope.items = items;
}
getItems();
// Ionic filter bar
var filterBarInstance;
$scope.visible = true;
$scope.nulledVisible = false;
$scope.toggle = function(event) {
if(event.target.id === 'nulled-search-button' && $scope.nulledVisible === false || event.target.id === 'header-search-button' && $scope.nulledVisible === false) {
$scope.visible = !$scope.visible;
$scope.nulledVisible = true;
}
};
$scope.showFilterBar = function () {
filterBarInstance = $ionicFilterBar.show({
items: $scope.items,
update: function (filteredItems, filterText) {
$scope.items = filteredItems;
if (filterText) {
console.log(filterText);
}
}
});
};
$scope.refreshItems = function () {
if (filterBarInstance) {
filterBarInstance();
filterBarInstance = null;
}
$timeout(function () {
getItems();
$scope.$broadcast('scroll.refreshComplete');
}, 1000);
};
}]);
services.js
angular.module('starter.services', [])
.service("ServicesData", [function () {
var servicesData = [
{
title: 'Car Repair and Maintenance',
total: 7,
id: 1
}
];
return {
getAllServices: function () {
return servicesData;
}
}])

2 things :
fix your controller declaration
["$scope", "ServicesData", function($scope, $timeout, $ionicFilterBar)
["$scope", "ServicesData", "$timeout", "$ionicFilterBar", function($scope, ServicesData, $timeout, $ionicFilterBar)
add dependency to your service module so your controller iwll be able to access what have been declared in your start.services module.
angular.module('starter.controllers', ['starter.services'])

Seems like you have an DI problem. Try to change this:
.controller('SearchCtrl', ["$scope", "ServicesData", function($scope, $timeout, ServicesData, $ionicFilterBar)
to:
.controller('SearchCtrl', ["$scope", "$timeout", "ServicesData", "$ionicFilterBar", function($scope, $timeout, ServicesData, $ionicFilterBar)

Rewrite dependency injection line.
.controller('SearchCtrl', ["$scope","$timeout","ServicesData", $ionicFilterBar, function($scope, $timeout, ServicesData, $ionicFilterBar)
the problem is sequence should be same and you have write dependency in both places.

Related

TypeError: Cannot read property 'go' of undefined in AngularJS

I am creating an web app, when splicing an object in a array. All of sudden, I am getting this error in the console that says: TypeError: Cannot read property 'go' of undefined.
Here is my code:
var app = angular.module("Portal", ['ngRoute', 'ui.bootstrap' ]);
app.controller('MainCtrl', MainCtrl);
$scope.inactive = true;
MainCtrl.$inject = ['$scope', '$window', '$timeout', '$state'];
function MainCtrl($scope, $window, $timeout, $state) {
$scope.deleteAction = function (people) {
$timeout(function () {
var index = $scope.userInfo.persons.indexOf(people);
console.log($scope.userInfo.persons);
$scope.userInfo.persons.splice(index, 1);
console.log($scope.userInfo.persons);
$state.go($state.current, {}, {reload: true});
$window.location.href = '#/person';
}, 100);
};
}
It seems that you are not injecting $state service. Notice the last parameter in your controller definition:
app.controller('MainCtrl', function($scope, $window, $timeout, $state) {
$scope.deleteAction = function (people) {
$timeout(function () {
var index = $scope.userInfo.persons.indexOf(people);
console.log($scope.userInfo.persons);
$scope.userInfo.persons.splice(index, 1);
console.log($scope.userInfo.persons);
$state.go($state.current, {}, {reload: true});
$window.location.href = '#/person';
}, 100);
};
});
Here is a recomended version of the controller definition, that plays nicely with code uglifiers:
app.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', '$window', '$timeout', '$state'];
function MainCtrl($scope, $window, $timeout, $state) {
$scope.deleteAction = function (people) {
$timeout(function () {
var index = $scope.userInfo.persons.indexOf(people);
console.log($scope.userInfo.persons);
$scope.userInfo.persons.splice(index, 1);
console.log($scope.userInfo.persons);
$state.go($state.current, {}, {reload: true});
$window.location.href = '#/person';
}, 100);
};
});

include ui bootstrap in angular js

How do I include ui.bootstrap. I use ui.bootstrap to open the bootstrap modal(open) on ng-click. After that I want to send all modal data to server, for that I use $http in my angular controller. But it gives an error. Below is my angular js code.
var app = angular.module("modalFormApp", ['ui.bootstrap']);
app.controller("modalAccountFormController", ['$scope', '$modal', '$log', '$http'
function($scope, $modal, $log, $http) {
$scope.showForm = function() {
$scope.message = "Show Form Button Clicked";
console.log($scope.message);
var modalInstance = $modal.open({
templateUrl: 'modal-form.html',
controller: ModalInstanceCtrl,
scope: $scope,
resolve: {
userForm: function() {
return $scope.userForm;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
]);
app.controller('ModalInstanceCtrl', ['$scope', '$http', '$modalInstance', userForm, function($scope, $http, $modalInstance, userForm) {
//var ModalInstanceCtrl = function ($scope, $modalInstance,$http, userForm) {
$scope.form = {}
$scope.url = 'submit.php';
$scope.submitForm = function() {
if ($scope.form.userForm.$valid) {
$http.post($scope.url, {
"name": $scope.name,
"email":
$scope.email,
"message": $scope.message
}).
success(function(data, status) {
console.log(data);
$scope.status = status;
$scope.data = data;
$scope.result = data;
})
} else {
console.log('userform is not in scope');
}
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
}])
'ui.bootstrap' has prerequisites 'ngAnimate' and 'ngTouch'. You should add them to your module
var app = angular.module("modalFormApp", ['ngAnimate','ngTouch','ui.bootstrap']);
And you should add their scripts to your view
script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.min.js")
script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-touch.min.js")

AngularJS: $routeParams to work within a service

I know this is easy, but I can't quite wrap my head around how to do this.
I need to do the API call within a service so that those variables can be accessed between two separate controllers.
The problem I am having is I can't access $routeParams (which I need for the get) within the service. I can't figure out know how to pass $routeParams from the controller to the service.
app.controller('Main', ['$scope', 'Page', '$routeParams', '$http', function($scope, Page, $routeParams, $http) {
$scope.Page = Page;
}]);
app.controller('Pages', ['$scope', 'Page', '$routeParams', '$http', function($scope, Page, $routeParams, $http) {
$scope.Page = Page.posts;
}]);
app.factory('Page', ['$routeParams', '$http', function($routeParams, $http) {
var posts = function posts() {
$http.get('wp-json/wp/v2/pages/?filter[name]='+ $routeParams.slug).success(function(res){
console.log(JSON.stringify(res) );
});
};
var description = '';
var title = '';
return {
title: function () { return title; },
setTitle: function (newTitle) { title = newTitle; },
description: function () { return description; },
setDescription: function (newDescription) { description = newDescription; },
posts
};
}]);
factory :
app.factory('Page', ['$http', function($http) {
var _posts = function posts(param) {
return $http.get('wp-json/wp/v2/pages/?filter[name]='+ param);
};
var description = '';
var title = '';
return {
title: function () { return title; },
setTitle: function (newTitle) { title = newTitle; },
description: function () { return description; },
setDescription: function (newDescription) { description = newDescription; },
posts : _posts
};
}]);
Controller :
app.controller('Pages', ['$scope', 'Page', '$routeParams', '$http', function($scope, Page, $routeParams, $http) {
Page.posts($routeParams.slug).then(function success(response) {
$scope.Page = response.data;
}, function error(reason) {
// do something
});
}]);
please note that success is deprecated in newer versions of Angular. I have updated the code with then

Angular $filter not available in promise callback

I'm injecting $filter into my controller and all is well until I try to use it in a promise callback. Here's the gist of the code
controller: ['$scope', '$filter', function($scope, $filter) {
geozipcodes.featured().$promise.then(function(res){
$scope.item = $filter('unique')(res, 'name');
});
}]);
This throws 'Uncaught ReferenceError: $filter is not defined'
However, if I do this
controller: ['$scope', '$filter', function($scope, $filter) {
var $filter = $filter;
geozipcodes.featured().$promise.then(function(res){
$scope.item = $filter('unique')(res, 'name');
});
}]);
Everything works as expected which I don't get at all. I should mention this is inside of an if/else statement, but that shouldn't have any bearing I don't think.
Has anyone experienced anything similar? The way I'm solving it feels really hacky plus I don't really understand why it works.
Update: more code for context
angular.module('ourApp').directive('searchItems', ['$timeout', '$rootScope', 'geozipcodes', 'baselistings', '$compile', '$stateParams',
function($timeout, $rootScope, geozipcodes, baselistings, $compile, $stateParams) {
return {
restrict: "E",
scope: {
performSearch: '&',
emptySetMessage: '#',
itemType: '#',
searchTrigger: '=',
toggleToolbar: '#',
noResults: '=?'
},
templateUrl: 'views/directives/search-items.html',
controller: ['$scope', '$rootScope', 'utils', 'companies', 'settings', 'geozipcodes', '$stateParams', '$filter',
function($scope, $rootScope, utils, companies, settings, geozipcodes, $stateParams, $filter) {
$scope.settings = settings;
$scope.searchType = $scope.itemType == 'student' || $scope.itemType == 'applicant' ? 'student' : $scope.itemType == 'listing' || $scope.itemType == 'application' || $scope.itemType == 'invitation' ? 'listing' : ''
$scope.items = []
$scope.searchInProgress = true;
$scope.initFilters = {};
$scope.pageFilters = {};
$scope.sortList = [];
if ($scope.searchType == 'first') {
// omitted
} else {
if ($scope.itemType == 'listing') {
listingtags.categories().$promise.then(function(res) {
$scope.tagCategories = res;
});
geozipcodes.featured().$promise.then(function(res){
$scope.defaultLocations = $filter('unique')(res, 'name');
});
}
}
...

Learning Angular Seed Notation

I was following a question (ui bootstrap modal's controller 'is not defined'), which I then tried modifying for nested controllers, different scoping calls, and renaming/refactoring the code (for learning).
I couldn't get it working in My Plunker, so that leaves me with a few questions:
Why is it not working?
The original question shows creating a new module, rather than appending controllers to the app module -- why? Is this recommended?
If PageController is the ancestor controller, how would it's $scope.open method reference the other controllers open definition?
Code:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('PageController', ['$scope',
function($scope) {
$scope.open = function() {
// how to call ModalController.open?
};
}
])
.controller('ModalController', ['$scope', '$modal', '$log',
function($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function() {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function() {
return $scope.items;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
])
.controller('ModalInstanceCtrl', ['$scope', '$modalInstance', 'items',
function($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function() {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
}
]);

Categories