AngularJS [$injector:unpr] Unknown provider: dataProvider <- data <- PageCtrl - javascript

I have seen the other answers and so far nothing has helped me. I get this error with the following code in a file:
angular.module('myApp.page', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/page/:pageId', {
templateUrl: 'page/view.html',
controller: 'PageCtrl',
resolve: {
data: function($q, $http, $routeParams) {
var deferred = $q.defer();
$http({method: 'GET', url: 'http://....' + $routeParams.pageId})
.then(function(data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
})
}])
.controller('PageCtrl', function ($scope, $rootScope, data) {
//do stuff
}
And in the app.js I have this:
angular.module('myApp', [
'ui.bootstrap',
'ngRoute',
'ngTouch',
'ngResource',
'myApp.page'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/'});
}]).
config(['$provide', Decorate])
Everything was working correctly and I fetched the data with the HTTP method with no problems, until I started using the Q library and moved the data fetching into the config section. Any tips? None of the other answers seem to work. Thanks in advance!

You issue is due to the fact that you are using ng-controller directive to instantiate the controller PageCtrl which takes a dynamic dependency data which is only created by the router. So when you inject a dynamic dependency via router resolve and having the router instantiate the controller, you do not need to and should not instantiate the controller via ng-controller it will simply fail due to the lack of dependency availability from the injector. router will manage the instantiation of the controller and setting it up for the respective view for you.
So just remove ng-controller from your view also make sure the partial represented by the route is complete enough to represent the view related to the controller functionality. Also i have seen it is a good practice not to start with a partial view with ng-controller and instantiate with route which will help making that partial view more reusable with a different controller. Also while creating a unit test you can easily mock the dynamic dependency and feed it via the $controller service.

Related

Unknown provider: userProvider for existing Yeoman AngularFire user service

I'm having some trouble injecting a service into a controller in a Yeoman AngularFire app.
Here is the controller(which is included by the Yeoman generator) that I am trying to inject user into:
angular.module('myYoApp')
.controller('ChatCtrl', function ($scope, user, Ref, $firebaseArray, $timeout) { ....
Which produces this Unknown provider error:
angular.js:12798 Error: [$injector:unpr] Unknown provider: userProvider <- user <- ChatCtrl
Strangely it works fine in my custom controller, allowing the user to be accessed in the associated view.
angular.module('myYoApp')
.controller('myCtrl', function ($scope, user, Auth, Ref, $firebaseArray, $firebaseObject, $timeout) { ....
I have no idea why the user service would be injectable in my custom controller but not in the Yeoman generated ChatCtrl. I've also looked all over the project and can't seem to find where the user service is coming from. But it's clearly somewhere in the app if my custom service can use it.
I've also tried using $user in place of user but that didn't fix it.
Cheers for any help figuring this out!
Ok.I managed to solve this. It was an oversight in the routes.js. The Yeoman angularfire-generator adds built-in routes security/authentication which is added to a route to easily block it from being accessed unless the user is logged in.
As a result, the user service can only be injected into a controller if the route uses $routeProvider.whenAuthenticated in place of $routeProvider.when.
Regular unsecured route looks like this:
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
Secured route looks like this:
$routeProvider
.whenAuthenticated('/chat', {
templateUrl: 'views/chat.html',
controller: 'ChatCtrl'
})

Passing dependencies to a module angular

So I am somewhat new to angular, but not javascript. I am working with an app someone else wrote and am trying to create a new controller in an existing module. The controllers are almost identical to each other as far as dependencies go. The question I have is how do I pass the same dependencies to both controllers? It seems like you would be able to pass them in like this:
`angular.module('ApertureForm', ['dialogs.main','dialogs.default-translations','ui.bootstrap'])`
When I do that for both modules, the controller returns undefined for whatever reason. Thats where I get stuck. How do you pass in dependencies such as the above code? Any advice would be great.
angular.module('ApertureForm', ['dialogs.main','dialogs.default-translations','ui.bootstrap']) tells AngularJS to initialize an Angular module named ApertureForm and also load other Angular modules as dependencies for the module.
To add dependencies to a controller, you do something like the following:
angular.module('ApertureForm').controller('ControllerName', function($scope, $location, $timeout) {...});
angular.module('ApertureForm') = Get the module named ApertureForm.
Then create a controller called ControllerName. The closure is where you inject dependencies.
To prevent a controller's dependencies from getting renamed on minification, you can do:
angular
.module('ApertureForm')
.controller('ControllerName', ControllerName);
ControllerName.$inject = ['$scope', '$location', '$timeout'];
function ControllerName($scope, $location, $timeout) {...}
Docs: https://docs.angularjs.org/guide/di
In angular.module('ApertureForm',[ you list the modules you want to inject to your module. You list in once for each module you have. If You want to create a controller in one of your modules, then your can use:
var myApp = angular.module('ApertureForm');
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
$scope here is a dependency for controller
You can read more about it here
AngularJS Controllers and Dependency Injection:
angular
.module('ApertureForm', ['dialogs.main','dialogs.default-translations','ui.bootstrap'])
.controller('FormController', ['$scope', '$http', function($scope, $http) {
// FormController code...
}])
.controller('WebinarController', ['$scope', '$http', function($scope, $http) {
// WebinarController code...
}]);
Thanks to everyone for the help! All of it was very useful in learning the structure of angular and how to properly use the framework. #Yosvel Quintero was able to explain how the module works and why I was getting the error. When dependencies are passed into the module, not the controller, they are available to all controllers as it the module it's self is now aware of the dependencies, which is why I kept getting errors trying to pass them again. Hopefully the answers given in response to the question can help someone learn angular as well. Thanks guys!

AngularJS - How to refer to a submodule controller from ui-router?

I'm struggling a bit with having submodules in an Angular 1.3.9 app. I've got a (non-working, sorry) preview at http://plnkr.co/edit/XBfTPAGRRe0CWJgjGJzc?p=preview and I think it's freaking out, in part, because I'm using Restangular.
I have the following:
angular
.module('estimate', ['ui.router', 'restangular', 'estimate.project'])
;
angular
.module('estimate.project', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider'
, function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('project', {
url: "/project/{id:int}",
abstract: true,
templateUrl: '/app/templates/project.html',
controller: "ProjectController as project",
resolve: { // stuff }
})
.state('project.overview', {
url: "",
templateUrl: "/app/templates/overview.html"
})
// ...
;
}])
.controller('ProjectController', ['$scope', 'ProjectService', 'myProject'
, function($scope, ProjectService, myProject) {
console.log('i made it!');
}]);
And in my template, which is served from the estimate module, I have:
<li><a ui-sref="project.overview({ id: 1 })">One</a></li>
The URL resolves correctly on the page, but clicking on it does nothing. It doesn't even throw any console errors - it just sits there. My gut tells me it has to do with how I'm referring to the controllers and/or the routes, and if they need to be prefixed or modified to work with a submodule. Any ideas on how to get it to load properly?
If this post is too scatterbrained, let me know and I'll try to clean it up.
I updated your plunker here and would say, that the most important change is - referencing sub-module in the main module:
Instead of this:
angular
.module('estimate', ['ui.router', 'restangular'])
...
angular
.module('estimate.project', ['ui.router'])
...
We have to use this, i.e. reference sub module in a parent module
angular
.module('estimate', ['ui.router', 'restangular', 'estimate.project'])
...
angular
.module('estimate.project', ['ui.router'])
...
With some few other small adjustments, that should be the way. Check it working here

Using Restangular with the same URL but different files

I need to communicate with a REST web service via Angular and I'm using RestAngular but I'm running into some difficulty. I have to use the same URL but GET & POST to two different files. I'm setting the base URL in my .config in the app.js and the service.js is where I'm setting the other URL via RestangularConfigurer. The BaseURL in the config has a query string appended to it. The second URL in the service does not. I want to GET from the BaseURL in the config and POST to the Factory from an input. Below is an example of my code
app.js
'use strict';
angular
.module('testApp', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'ui.bootstrap',
'ngGrid',
'google-maps',
'ngMessages',
'restangular'
])
.config(function (RestangularProvider, $routeProvider) {
RestangularProvider.setBaseUrl('http://dev.domain.com:9005/question-ws.htm?&areacode=215');
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
});
service.js
'use strict';
angular.module('testApp')
.factory('NextRestangular', function($http, $sce, Restangular){
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('http://dev.domain.com:9005/next-question-ws.htm');
});
});
controller.js
'use strict';
angular.module('testApp')
.controller('ScreenCtrl', function ($scope, Restangular, NextRestangular) {
Restangular.all().getList();
NextRestangular.all().getList();
});
I can't seem to GET from Restangular and I can't POST to NextRestangular. Will the file structure be able to support this? Am I going about this all wrong?
Restangular is a service to handle Rest API Restful Resources.
The .htm in your URLs leads me to believe the response is not JSON. I don't believe Restangular will work for you if that is the case. I recommend looking into ngResource or even $http. If your response is JSON, the following should help get you on your way.
In this example, the baseUrl should be "http://dev.domain.com:9005".
RestangularProvider.setBaseUrl('http://dev.domain.com:9005');
I have not used setRequestSuffix before but that may allow you to also have the .htm.
RestangularProvider.setRequestSuffix('.htm');
Then your API calls should look something like this.
Restangular.all('next-question-ws').get({areacode: 215});
Restangular.all('next-question-ws').post(
// JSON Payload here.
});

AngularJS: Error when injecting $modal inside a controller that is nested inside of a directive

We have a custom directive that generates html around a checkbox. This uses transclusion to inject the contents that are passed within it. It looks something like this:
somecheckbox.js
angular.module('namespace.directives')
.directive('someCheckbox', function() {
return {
templateUrl: 'directives/checkbox.html';
restrict: 'E',
transclude: true
}
}]);
directives/checkbox.html
<label class="styling" ng-transclude>
... some other html
</label>
We extensively use modals throughout our application and are in the process of converting everything to bootstrap's angular directive. We've created a controller that handles a particular type of modal that appears sporadically throughout out application:
angular.module('namespace.controllers').controller('LegalModalController',
['$scope', '$modal',
function($scope, $modal) {
$scope.showLegalModal = function(title, legalTextLocation) {
$modal.open({
templateUrl: 'modals/legal.html',
controller: 'sc.LegalModalInstanceController',
resolve: {
modalTitle: function() {
return title;
},
template: function() {
return eulaTextLocation;
}
}
});
};
}]);
Coming back to the directive piece, there is a case where we need to add a link within the checkbox directive that hooks into the legal controller to pop open a modal window. This is what's being done thus far:
<some-checkbox>Click <a href ng-controller="LegalModalController" ng-click="showLegalModal()">here</a> to...</some-checkbox>
The problem that we're encountering is that we have been thoroughly unable to inject $modal into the controller without getting the following error:
Unknown provider: $modalProvider <- $modal
I've looked everywhere, but I haven't found any others who are in this scenario. Does anyone know what could be the potential root of this problem? This linking works in every case where we are not using a directive.
This is the main.js file that starts up the app:
angular.module('namespace.modules.main', ['namespace.core', 'ui.select2', 'ngSanitize', 'ui.sortable', 'infinite-scroll', 'ui.bootstrap']).
config(['$routeProvider', '$locationProvider', '$httpProvider', '$compileProvider',
function($routeProvider, $locationProvider, $httpProvider, $compileProvider) {
routeProvider = $routeProvider;
$locationProvider.html5Mode(true).hashPrefix('!');
$httpProvider.defaults.headers.patch = {};
$httpProvider.defaults.headers.patch['Content-Type'] = 'application/json; charset="UTF-8"';
// Allow telephone hyperlinks
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|mailto|tel):/);
}]).run(
['$rootScope', '$location', '$timeout', '$window', '$route'
function($rootScope, $location, $timeout, $window, $route) {
// set up $rootScope and route provider here
});
I was able to figure it out. The specific page within our application that this was failing on was its own module, and thus didn't have the correct bootstrap ui dependencies. Oops >.< .

Categories

Resources