Angular: Not able to access variables in controller using service - javascript

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.

Related

Angular doesn't work when defining a service and factory separately

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()
];
}]);

AngularJS service object is not being updated across views/controllers

I have a factory, "itemData", that holds a service.
app.factory('itemData', function () {
var itemData = {
Title: 'I should be different',
getTitle: function () {
return itemData.Title;
},
setTitle: function (title) {
return itemData.Title=title;
},
// This is the function to call all of the sets for the larger object
editItem: function (entry)
{
itemData.setTitle(entry);
}
};
return itemData;
});
I have 2 controllers (in different files) associated with 2 separate views.
The first:
// IndexCtrl
app.controller("IndexCtrl", ['$scope','$window','itemData',
function($scope, $window, itemData) {
var entry = "I'm different";
// After a submit is clicked
$scope.bttnClicked = function (entry) {
itemData.editItem(entry);
console.log(itemData.getTitle(); //<--itemData.Title has changed
// moves to page with other controller
$window.location.href = "edit.html";
};
}
]);
and the second, which is not doing what I want:
app.controller("editItemCtrl", ['$scope', '$window', 'itemData',
function ($scope, $window, itemData){
$scope.item = {
"Title": itemData.getTitle(), //<--- Title is "I should be different"
}
}]);
Do you have some kind of router in place in your Angular app? When you change the location href, is it actually causing full page reload?
Services are held in memory and therefore will not maintain state across page reloads.
I consider that the expression ['$scope', '$window', 'itemData',
function ($scope, $window, itemData) force to initialize the dependency injection and for this reason you had two different object.
if you see the doc https://docs.angularjs.org/guide/controller there is a section called Setting up the initial state of a $scope object in this section was described the case of scope but I consider that may be extended at the list of the service in the [...] even in the angular.module(moduleName,[...]) if the [....] are filled the functin return a new module and only for empty square bracket return the current module instance
I hop that this can help you

Error: [$injector:nomod] Module is not available

I am trying to upload a file with progress bar but getting 2 errors constantly, no matter what i do
1)module not defined and 2nd is [$injector:nomod] module not available.
http://jsfiddle.net/3m75wqt1/
this is my controller
PageController.js
var PageController = function ($scope, fileUpload ) {
angular.module('app', ['ngProgress'])
angular.module('app')
.controller('PageController', function ($scope) {
//$scope.fileUpload = {};
});
PageController.$inject = ['$scope','ngProgress'];
};
I have done a lot of searching but unable to find the error.
any help would be appreciated... Thanks in advance
First at all the module method shoud not be called inside of a controller, so this:
var PageController = function ($scope, fileUpload) {
angular.module('app', ['ngProgress'])
angular.module('app')
.controller('PageController', function ($scope) {//I will replace this with PageController
//$scope.fileUpload = {};
});
PageController.$inject = ['$scope', 'ngProgress'];
};
shoud look more like this:
var PageController = function ($scope, fileUpload) {
};
PageController.$inject = ['$scope', 'ngProgress'];
angular.module('app', ['ngProgress'])
angular.module('app').controller('PageController', PageController);
i removed the function in your controller method and put your defined PageController at its place
The second thing is that you dont need to call the module method twice, the first one is already returning the module, so the best approach shoud look like this:
var PageController = function ($scope, fileUpload) {
};
PageController.$inject = ['$scope', 'ngProgress'];
angular.module('app', ['ngProgress']).controller('PageController', PageController);
And i personaly like the array notation more than this, so my favorite would look like this, but that is up to you:
angular.module('app', [
'ngProgress'//this is a module dependency (its also createt with angular.module)
]).controller('PageController', [
'$scope',
'fileUpload',//this is a dependency for the controller (probably a service)
function ($scope, fileUpload) {
}
]);

AngularJS : watching Service properties

Take the following plunk as an example:
http://plnkr.co/edit/vKFevXhhSprzFvesc6bG?p=preview
var app = angular.module('plunker', []);
app.service('SomeService', ['$rootScope', function ($rootScope) {
var service = {
value: false
}
return service;
}]);
app.controller('MainCtrl', ['$scope', 'SomeService', function($scope, SomeService) {
$scope.value = SomeService.value;
//$scope.$watch(function () { return SomeService.value; }, function (data) { $scope.value = data; });
}]);
app.controller('SecondaryCtrl', ['$scope', 'SomeService', function($scope, SomeService) {
$scope.toggleValue = function () {
SomeService.value = !SomeService.value;
}
}]);
2 controllers and a service, 1 controller (SecondaryCtrl) updates a property on the service and the other controller (MainCtrl) references this property and displays it.
Note the $watch expression commented out in MainCtrl - with this line uncommented, everything works as expected but my question - is it necessary? Shouldn't the watch be implicit or am I doing something wrong?
When you assign the value of SomeService.value to your scope variable, you are creating a copy of the variable which is a distinct object from the value inside SomeService. By adding the watch expression you were simply keeping the two variables (the one in the scope and the one in SomeService) synchronised.
The easiest way to go about this is not to copy the value, but create a reference to the service itself. So in MainCtrl
$scope.someService = SomeService;
and in your html
Value: {{someService.value}}
this way you are actually binding to the value inside SomeService.

AngularJS $rootScope variable exists, but not accessible

I set a $rootScope variable in one of my modules and now want to access that same $rootScope variable in another module. Thus far I can see that in both modules the variable has been set properly, but when I try accessing the variable in $rootScope, I only get undefined.
How can I access this variable without doing a factory/service workaround? The variable is really simple and $rootScope should suffice for what I need. I've put some generic sample code below to illustrate the issue:
file1.js
var app = angular.module('MyApp1', []);
app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.myFunc = function() {
$rootScope.test = 1;
}
}
file2.js
var app = angular.module('MyApp2', []);
app.controller('Ctrl2', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.need_to_access_this = $rootScope.test; // undefined
console.log($rootScope); // returns JS object w/ test property set to 1
}
I was just stuck in the same problem when I figured out that you have define those properties for $rootScope before the controllers or services load. So what I did was set inital values when the application runs. In your case it will be like:
app.run(function($rootScope){
$rootScope.test="variable";
})
`
In Ctrl1 the $rootScope.test value is set inside the $scope.myFunc.
The problem is that you aren't calling that function, so the test property in $rootScope is never set.
You need to call $scope.myFunc(); in Ctrl1 or set $rootScope.test = 1; dirrectly in the Controller:
app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.myFunc = function() {
$rootScope.test = 1;
};
$scope.myFunc();
}
or
app.controller('Ctrl1', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.test = 1;
}
EDIT:
The above suggestions still remain valid, thus you need to call myFunc().
But the problem with your code is that Ctrl1 belongs to MyApp1 and Ctrl2 belongs to MyApp2.
Every application has a single root scope (docs here)
You will need to create Ctrl2 as a controller of MyApp1:
angular.module('MyApp1')
.controller('Ctrl2', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.need_to_access_this = $rootScope.test; // undefined
console.log($rootScope); // returns JS object w/ test property set to 1
}]);

Categories