I am trying to obfuscate my angularjs app and it is breaking. I am aware that this is an issue with the framework and they have tried to remedy it via the $inject method.
http://docs.angularjs.org/tutorial/step_05 See the "Note on Minification" section.
To resolve this they recommend doing YourController.$inject = ['$scope', '$http'];
I went ahead and did that to match my application like so:
AventosController.$inject = ['$scope','$http','$q','controllerComm'];
VforumController.$inject = ['$scope','$http','$timeout','controllerComm'];
Well, it still isn't working. The error I receive in the console is:
Error: Unknown provider: cProvider <- c <- controllerComm
Anyway to remedy this?
EDIT
controllerComm
app.factory('controllerComm', ['$rootScope', function($rootScope)
{
var showVforum = {};
showVforum.result = false;
showVforum.prepBroadcast = function(val)
{
this.result = val;
this.broadcastVal();
}
showVforum.broadcastVal = function()
{
$rootScope.$broadcast('toggleVforum')
}
return showVforum;
}]);
EDIT 2 not working after obfuscation
$scope.launchVforum = function()
{
$scope.installationVideo = ($scope.installationVideo) ? false : true;
controllerComm.prepBroadcast($scope.installationVideo);
}
Try injecting at the controller definition.
app.controller('myCtrlr', ['$scope', '$http', '$q', 'controllerComm', function ($scope, $http, $q, controllerComm) {
...
}]); // end myCtrlr
Also is "controllerComm" defined?
Related
I'm trying to write a simple angular service and a factory like below:
html:
<div ng-controller="mycontroller">
{{saycheese}}
</div>
Javascript
var myApp = angular.module('myApp', []);
myApp.service('myservice', function() {
this.sayHello = function() {
return "from service";
};
});
myApp.factory('myfactory', function() {
return {
sayHello: function() {
return "from factory!"
}
};
});
//defining a controller over here
myapp.controller("mycontroller", ["myfactory", "myservice", function(myfactory, myservice) {
$scope.saycheese = [
myfactory.sayHello(),
myservice.sayHello()
];
}]);
But the JSFiddle still just displays {{saycheese}} instead of angular mapping the function.
Link to my fiddle:
http://jsfiddle.net/PxdSP/3047/
Can you point me where am I going wrong in this case ? Thanks.
You have several syntax errors in your code, and checking the console would have helped without questioning the SO. Here's one possible way to write the controller (demo):
myApp.controller("mycontroller", ["$scope", "myfactory", "myservice",
function($scope, myfactory, myservice) {
$scope.saycheese = [
myfactory.sayHello(),
myservice.sayHello()
];
}]);
Apart from obvious fix myapp => myApp (variable names are case-sensitive in JavaScript), $scope should be passed into controller as an argument (and mentioned as its dependency if using arrayed - proper - form of controller definition, as you did) before you can access it. Otherwise you just get ReferenceError: $scope is not defined exception when controller code is invoked.
Couple things:
myapp.controller(...) should be myApp.controller(...)
You need to inject $scope in your controller.
Fixed controller:
myApp.controller("mycontroller", ["myfactory", "myservice", "$scope", function(myfactory, myservice, $scope) {
$scope.saycheese = [
myfactory.sayHello(),
myservice.sayHello()
];
}]);
I am trying to share a variable between a controller and a function. But i get an error from the controller, saying this:
TypeError: Cannot read property 'getSet' of undefined
I have gone through numerous tutorials, but don't know where am I going wrong.
My service code is like this:
app.service('shareData', function() {
var selected = ["plz", "print", "something"];
var putSet = function(set) {
selected = set;
};
var getSet = function() {
return selected;
};
return {
putSet: putSet,
getSet: getSet
};
});
I am able to reach selected from my function defined like this:
setDisplay = function($scope, $mdDialog, shareData) {
console.log(shareData.getSet()); // this is working
$scope.selected = shareData.getSet();
$scope.hide = function() {
$mdDialog.hide();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.answer = function(answer) {
$mdDialog.hide(answer);
};
};
My controller is like this:
app.controller('topicController', ['$scope', '$http', '$mdDialog', 'shareData',
function ($scope, $http, $mdDialog, $mdToast, shareData) {
console.log(shareData.getSet()); // NOT WORKING
}]);
You had extra $mdToast in your topicController controller's factory function, you need to remove it.
The reason behind it was not working is, currently you had 4 dependency mentioned in array like ['$scope', '$http', '$mdDialog', 'shareData', function & then you are using its instance inside the function next to DI array. Inside that function you had actually 5 dependencies where $mdToast extra. So behind the scene what happening is $scope of function hold an value of '$scope' DI array likewise you go right to left. But when it comes to $mdToast(in controller function) it was holding a value of 'shareData'(of DI array) & then the next parameter shareData get nothing.
app.controller('topicController', ['$scope', '$http', '$mdDialog', 'shareData',
function ($scope, $http, $mdDialog, shareData) { //<--removed $mdToast
console.log(shareData.getSet());
}
]);
NOTE: You are using DI inline array annotation, so the sequence in which dependency are injected in array, in same sequence you should
inject then in underlying factory function.
I dont understand what I am missing
I dont get result on html i think this problem managing with controllerAs syntax
note: I can see the result in console console.log(this.movie); - its from controller
app.js
var app = angular.module('mfApp',['ngRoute', 'appControllers']);
app.config(function($routeProvider){
$routeProvider.
when('/:detail',{
templateUrl: 'template/detail.html',
controller : 'detailCtrl' ,
controllerAs: 'movieAs'
}).otherwise({
redirectTo: '/'
});
});
controller.js
var mfControllers = angular.module('appControllers', []);
mfControllers.controller('detailCtrl', ['$scope', '$routeParams', 'appServices', function($scope, $routeParams, appServices){
this.movie = [];
this.id = $routeParams.detail;
appServices.homeSearch(this.id).success(function(response){
this.movie = response;
console.log(this.movie);
// Yes, I do get array result in console
});
}]);
html - template/detail.html
My try
{{movieAs.Title}}
{{movieAs.movie.Title}}
{{movie.movieAs.Title}}
{{movie.Title}} {{title}}
mfControllers.controller('detailCtrl', ['$scope', '$routeParams', 'appServices', function($scope, $routeParams, appServices){
var me = this;
me.movie = [];
me.id = $routeParams.detail;
appServices.homeSearch(me.id).success(function(response){
me.movie = response;
console.log(me.movie);
// Yes, I do get array result in console
});
}]);
EDIT
In Javascript functions are stored as objects, so from your callbeck method inside succeess, you call this which refers to the method that you are running and not to the controller scope.
It is best practice to store the reference to the controller in a variable which can be accessed by the callback methods. me is quite an arbitrary name but widely used to refer as the parent caller. https://github.com/johnpapa/angular-styleguide
The problem is due to wrong this reference.
var mfControllers = angular.module('appControllers', []);
mfControllers
.controller('detailCtrl', ['$scope', '$routeParams', 'appServices', function($scope, $routeParams, appServices) {
var vm = this;
vm.movie = [];
vm.id = $routeParams.detail;
appServices
.homeSearch(vm.id)
.success(function(response) {
// vm !== this; here
vm.movie = response;
console.log(vm.movie);
});
}]);
A good practice when using controllerAs syntax is to assign this to vm at the very beginning of a controller. It holds the reference of the controller correctly.
That is necessary because of javascript function scoping. It will be long to explain it here, but the gist of it is that function creates a new scope, this inside a function will be different. Todd Mott has a very great write up on this.
I have looked over many threads of this error, yet following the instructions on 2 of them, it still throws the same error, here is my service:
angular.module('sccateringApp')
.service('httpcalls', function ($scope, $http) {
var BackEndBaseURL = "methods/server.php";
return {
..
}
});
And here is my controller:
angular.module('sccateringApp')
.controller('newCategoryController', ['httpcalls', '$scope', function (httpcalls, $scope) {
$scope.submitForm = function(){
alert();
}
}]);
I can't really identify what the problem is, since I already included the service per se as a dependency of the controller. Any help will be much appreciated!
Update: Phil is right, the real provider error comes from the dependency on $scope, credits to him when he post it.
It looks like you are creating a factory and not a service.
You don't need to return anything from a service, but declare things in the this (it is a prototype instanciation, like a class).
sccateringApp.service('httpcalls', function ($scope, $http) {
var BackEndBaseURL = "methods/server.php";
this.someMethod = function() { ... }
this.someProperty = ...
});
Otherwise, just replace module.service by module.factory
I'm fairly new to the AngularJS framework, but basically what I am trying to do is inject a CSRF token into my app, but I want to change the url based on a config. Here is what I have so far:
var VERISION_API = 'v1';
var config_data = {
'CFG': {
'EP': 'https://mydomain.com/api/' + VERISION_API + '/web/'
}
};
var configMod = angular.module("cfg",[]);
angular.forEach(config_data,function(key,value) {
configMod.constant(value,key);
});
var myApp = angular.module("app", ["cfg", "ngResource", "ngRoute"]);
(function () {
var $injector = angular.injector(['ng']);
$injector.invoke(['cfg', '$http', '$rootScope', function (cfg, $http, $rootScope) {
$rootScope.$apply(function (CFG) {
$http.get(CFG.EP + "accounts/csrf").then(function (response) {
myApp.constant("CSRF_TOKEN", response.csrf_token);
angular.bootstrap(document, ['app']);
});
});
}]);
})();
I keep getting the following error:
Uncaught Error: [$injector:unpr] Unknown provider: cfgProvider <- cfg
I know it has something to do with the way that I am running the $injector.invoke, but I have tried everything. Hopefully someone could help me out and tell me what I am doing wrong?
Couple of issues, See inline:-
var $injector = angular.injector(['ng', 'cfg']); //<-- Add module name here
/*Injection is case sensitive it mustbe CFG*/
$injector.invoke(['CFG', '$http', '$rootScope', function (cfg, $http, $rootScope) {
$rootScope.$apply(function () { //Do not set an argument here
$http.get(cfg.EP + "accounts/csrf").then(function (response) {
myApp.constant("CSRF_TOKEN", response.csrf_token);
angular.bootstrap(document, ['app']);
});
});
}]);
1) You need to get the injector with the module that has the dependency, example:
var $injector = angular.injector(['ng', 'cfg']);
2) DI service/provider/etc.. names are case sensitive so:
$injector.invoke(['CFG',...
3) Do not pass an argument in the anonymous function of $rootScope.$apply it will create a local variable within that scope. So just:
$rootScope.$apply(function () {
injected dependency is available as variable (argument cfg) from the upper scope, so just access it as:
$http.get(cfg.EP + "accounts/csrf");
Check the network console in the demo:
var configMod = angular.module("cfg", []);
var config_data = {
'CFG': {
'EP': 'https://mydomain.com/api//web/'
}
};
var configMod = angular.module("cfg", []);
angular.forEach(config_data, function(key, value) {
configMod.constant(value, key);
});
var myApp = angular.module("app", ["cfg", "ngResource", "ngRoute"]);
(function() {
var $injector = angular.injector(['ng', 'cfg']); //<-- Add module name here
/*Injection is case sensitive it mustbe CFG*/
$injector.invoke(['CFG', '$http', '$rootScope',
function(cfg, $http, $rootScope) {
$rootScope.$apply(function() { //Do not set an argument here
$http.get(cfg.EP + "accounts/csrf").then(function(response) {
myApp.constant("CSRF_TOKEN", response.csrf_token);
angular.bootstrap(document, ['app']);
});
});
}
]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
angular gets service from providerCache by exact the string key case sensitive, so CFG should be used