Cannot get to $rootScope - angularjs

The following file "works" (the sense that it does not throw any errors):
<!doctype html>
<html ng-app="modx">
<script src="http://code.angularjs.org/angular-1.0.0rc7.js"></script>
<script>
angular.module("modx", [], function($routeProvider) {
});
</script>
</html>
but this
<!doctype html>
<html ng-app="modx">
<script src="http://code.angularjs.org/angular-1.0.0rc7.js"></script>
<script>
angular.module("modx", [], function($routeProvider, $rootScope) {
});
</script>
</html>
gives the error:
Error: Unknown provider: $rootScope from modx
Source File: http://code.angularjs.org/angular-1.0.0rc7.js
Line: 2491
WTF?

You can not ask for instance during configuration phase - you can ask only for providers.
var app = angular.module('modx', []);
// configure stuff
app.config(function($routeProvider, $locationProvider) {
// you can inject any provider here
});
// run blocks
app.run(function($rootScope) {
// you can inject any instance here
});
See http://docs.angularjs.org/guide/module for more info.

I've found the following "pattern" to be very useful:
MainCtrl.$inject = ['$scope', '$rootScope', '$location', 'socket', ...];
function MainCtrl (scope, rootscope, location, thesocket, ...) {
where, MainCtrl is a controller. I am uncomfortable relying on the parameter names of the Controller function doing a one-for-one mimic of the instances for fear that I might change names and muck things up. I much prefer explicitly using $inject for this purpose.

I don't suggest you to use syntax like you did. AngularJs lets you to have different functionalities as you want (run, config, service, factory, etc..), which are more professional.In this function you don't even have to inject that by yourself like
MainCtrl.$inject = ['$scope', '$rootScope', '$location', 'socket', ...];
you can use it, as you know.

Related

Angular having controllers and services in different files

I have two controllers and one service in my angular app splitted in 3 different files as follows:
Main controller
var app = angular.module("app",[]);
app.controller("mainController", function(){
console.log("Hi main controller");
})
Second controller
var app = angular.module("app");
app.controller("secondController", ['myCoolService', function($rootScope, myCoolService){
console.log("Hi second controller")
}]);
Service
var app = angular.module("app");
app.service('myCoolService', function() {
});
I've made sure I was importing it correctly:
<script type="text/javascript" src="js/controllers/mainController.js"></script>
<script type="text/javascript" src="js/services/myCoolService.js"></script>
<script type="text/javascript" src="js/controllers/secondController.js"></script>
However I'm getting an unknown service exception:
Unknown provider: $resourceProvider <- $resource <- myCoolService
Can someone help me?
Should be:
var app = angular.module("app");
app.controller("secondController", ['$rootScope', 'myCoolService',
function($rootScope, myCoolService){
console.log("Hi second controller")
}
]);
See, AngularJS injector either gets names of specific dependencies from an array - or uses factory function arguments for them. The first way is actually recommended, as it withstands minification and lets Angular skip parsing the function's argument list.
The point is, AngularJS won't mix those approaches: if list of deps is specified, it IS used, and any hints given by arguments are just ignored. That's why your original code actually puts myCoolService into $rootScope variable (the first dependency is assigned to the first argument), but just doesn't know where to find the second one.
In your second controller you are missing dependency.
var app = angular.module("app");
app.controller("secondController", ['$rootScope', 'myCoolService', function($rootScope, myCoolService){
console.log("Hi second controller")
}]);

debugging angular 'unknown provider'

I'm trying to get this fileuploader plugin working on a page (it's actually .cshtml, but hopefully that's not the source of the problem). I don't know how to debug angular references to find out what's missing.
The fileuploader does work in a different place in the app:
markup: Views\Shared_MasterClientLayout.cshtml
<script src="#Html.GetContentPathAbsolute()/Content/lib/angular-file-upload/angular-file-upload.min.js"></script>
<body id="ng-app" ng-app="clientPortal"
controller: www\public\app\disabilities\disabilities.app.js
(function () {
'use strict';
var app = angular.module('disabilities', ['angularFileUpload']);
app.controller('disabilitiesController', ['$scope', '$rootScope', '$routeParams', '$fileUploader', disabilitiesController]);
function disabilitiesController($scope, $rootScope, $routeParams, $fileUploader) {
}
})();
But it does not work on my page:
markup: Views\Referral\ThankYou.cshtml
<script src="#Html.GetContentPathAbsolute()/Content/lib/angular-file-upload/angular-file-upload.min.js"></script>
<div id="ng-app" ng-app="cmorApp">
controller: ReferralContent\app\CreateReferral\cm.attachmentUploadCtrl.js
var AttachmentUploadCtrl = ['$scope', '$http', '$fileUploader',
function ($scope, $http, $fileUploader) {
I get
Uncaught Error: [$injector:unpr] Unknown provider: $fileUploaderProvider <- $fileUploader
I can see on the Sources tab in Dev tools that angular-file-upload-min.js has been loaded.
The worst part about this is a lack of consistency of implementation across pages that the various components are spread across. I know of no way to debug angular empirically.
I literally have no way to tell which of several apps is running, which controller is attached to a page and which is referring to what page.
Is there any way of inspecting a page and exposing what objects are loaded on it?
Can I write console.log(ng-app) and have it return 'cmorApp'?
Or console.log(app.controller) and have it return 'AttachmentUploadCtrl'?

AngularJS Unknown provider: $dialogProvider <- $dialog

I have a project which I would like to add a modal to. Great, so I read up and it sounds like the way to go is by using $dialog. I've got angular already, I've got bootstrap and bootstrap-ui.
Reading a post from 2013, they say "Hey, go get The Angular-UI Module, that's where $dialog is!"
Okay, I went to the angular-ui site, and unless I'm really stupid (and maybe I am) there is no such thing as The Angular-UI Module. Nor can I figure out easily which file on that site (since there are a WHOLE bunch) would contain the magical $dialog.
Help?!
This is being included:
<script src="lib/AngularJS/angular.js"></script>
<script src="lib/AngularJS/angular-route.js"></script>
<script src="lib/AngularJS/angular-sanitize.js"></script>
<script src="lib/jQuery/jquery-2.1.1.js"></script>
<script src="lib/bootstrap/js/bootstrap.js"></script>
<script src="lib/bootstrap-ui/ui-bootstrap-tpls-0.12.0.js"></script>
<script src="lib/lodash/lodash.min.js"></script>
<script src="lib/angular-file-upload/dist/angular-file-upload-all.js"></script>
var myApp = angular.module("myApp",
['ngRoute',
'angularFileUpload',
'ui.bootstrap.tpls',
'ui.bootstrap.rating',
'ui.bootstrap',
'ngMap',
'ngSanitize']
);
myApp.controller('myController',
['$scope','$rootScope', '$dialog',
function ($scope, $rootScope, $dialog) {
If I remove $dialog from the controller, everything is fine. As soon as I put it in there, I get the unknown provider error.
What you most likely want is $modal
myApp.controller('myController',
['$scope','$rootScope', '$modal',
function ($scope, $rootScope, $modal) {
Read more about it here: http://angular-ui.github.io/bootstrap/#/modal
If I remember correctly, is used to be called $dialog and was since changed.

AngularJS: Error 'Controller is not defined' when calling abstract controllers from another controller

In My angular JS application i have 2 pages using same functionality and i am trying to use abstract controller and i am getting 'Base Ctrl is not defined' error from Summary Ctrl.
am I missing anything...
Markup
<div ng-controller="MainCtrl">
<div ng-controller="SummaryCtrl">{{name}}</div>
<div ng-controller="SearchCtrl"></div>
</div>
MaintCtrl.js
define(['tabs/module'], function (module) {
'use strict';
module.controller('MainCtrl', ['$scope', function ($scope) {
//some code;
}]);
function BaseCtrl($scope) {
$scope.name="test";
}
});
SummaryCtrl.js
define(['tabs/summary/module'], function (module) {
'use strict';
module.controller('SummaryCtrl', ['$scope', function ($scope) {
BaseCtrl($scope);
//child actions`enter code here`
$scope.name = 'Clicked from base controller';
}]);
});
It looks to me like you're using this code as your example:
Angular: Extending controller
I'm still not 100% sure what your problem is, but it seems to me like it could be that in this sample you've supplied, both the code pieces are in the same file. When you do separate it into separate files, make sure when you bootstrap or add your *.js file references.. make sure you add base before the others that are 'dependent' on it
EG
<script language="javascript" src="someUrl/BaseCtrl.js"></script>
<script language="javascript" src="someUrl/SummaryCtrl.js"></script>
EDIT:
Your issue could be with RequirejJS
Have a look at
http://solutionoptimist.com/2013/09/30/requirejs-angularjs-dependency-injection/
Your MainModule is registered in 'tabs/module', but nowhere are you supplying SummaryCtrl any of its dependencies.
EG. SummaryCtrl is not implicitly aware of 'tabs/module', as it's in 'tabs/summary/module'
Try adding this to summary:
define(['tabs/summary/module', 'tabs/module'], function (module, BaseCtrl) {
'use strict';
module.controller('SummaryCtrl', ['$scope', function ($scope) {
BaseCtrl($scope);
//child actions`enter code here`
$scope.name = 'Clicked from base controller';
}]);
});

Using JSON as a service in AngularJS

I realise there are a few answers to this question on here, but I just can't seem to get them working with my set up. This is a Plunker of what I am trying achieve (not my own work): http://plnkr.co/edit/Ofq7Md8udEnIhAPF1NgL?p=preview
Currently, I have this for my index.html file:
<body ng-app="HomeCourtArenaApp">
<div class="container" ng-view></div>
<script src="components/angular/angular.js"></script>
<script src="components/require/require.js"></script>
<script src="components/angular/angular-resource.js"></script>
<script src="scripts/services/data.js"></script>
<script src="scripts/app.js"></script>
</body>
To register the components, I have defined them in the karma.conf.js file:
files = [
JASMINE,
JASMINE_ADAPTER,
'app/components/angular/angular.js',
'app/components/angular/angular-resource.js',
'app/components/angular-mocks/angular-mocks.js',
'app/scripts/*.js',
'app/scripts/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
];
To then create the service, I use the same technique that seems to be documented online in most examples:
'use strict';
angular.module('jsonData', ['ngResource'])
.factory('jsonData', function($resource) {
return $resource('data/shoe3Dconfig.js');
});
Where an error seems to be triggered is when I try to define the service in my 'app' variable, where adding the service name stops the content loading ['jsonData']:
'use strict';
var app = angular.module('HomeCourtArenaApp', ['jsonData']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
});
I would share my views and controllers also, but before I can even use the JSON data in my template, there are an unearthly amount of errors to deal with:
Uncaught Error: Module name "path" has not been loaded yet for context: _. Use require([])
Uncaught Error: Mismatched anonymous define() module: function () {
return getStyleProperty;
}
Uncaught Error: No module: ngResource
There are some other errors also, but these seem to be mainly because the scripts further up the DOM are stopping them loading correctly. Any help would be great!
you could try this :
the app.js:
angular.module('HomeCourtArenaApp', ['HomeCourtArenaApp.services', 'HomeCourtArenaApp.controllers']).
config(['$routeProvider', ($routeProvider) {
$routeProvider.when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl' });
$routeProvider.otherwise({ redirectTo: '/'});
}]);
angular.module('HomeCourtArenaApp.services', ['ngResource']).
factory('JsonData', function($resource){
return $resource('data/shoe3Dconfig.js');
});
angular.module('HomeCourtArenaApp.controllers', []).
controller('MainCtrl', ['$scope', 'JsonData', function($scope, JsonData) {
$scope.objs = JsonData.query();
console.log(objs);
}
}]);
and this is not necessary to load the datas in the html
<script src="scripts/services/data.js"></script>
This edited plunker http://plnkr.co/edit/33qW5VRnQVrHWFlp16kz?p=preview should get you further along the way.
You need to specify the module (jsonData) that you want in your app as a dependency. There is currently no name displayed since your data does not have a name property.
Your JSON service module definition named as 'jsonData'
angular.module('jsonData', ['ngResource'])
This module defines a service provider (factory) 'jsonService'
.factory('jsonService', function($resource) {
You list the 'jsonData' module as a dependency for your module so that you can access anything defined in there
var app = angular.module('plunker', ['jsonData']);
You then use Angular's Dependency Injection to request an instance of jsonService
app.controller('MainCtrl', function($scope, jsonService) {
Note that if you "production-ise" this and minify your JS, you will need to configure the DI code. I will leave that to you to find in the Angular docs.
Does this explain things a bit more?
And you can get the console in plunker by opening the developer tools in your browser.

Resources