Angular JS Service not defined - javascript

I'm trying to create a universally accessible array in my application using services. I also implement ui-router in my appliaction.
I create the service in my app.js:
myFamilyApp.service('global', function() {
var eventArray = [];
return {
addEvent: function() {
eventArray.push(newObj);
}
}
});
then I call it from my controller:
myFamilyApp.controller('newEventController', [ '$scope', '$state',
function($scope, $state, global) {
eventConfig = {//variables to create event};
e = new Event(eventConfig);
global.addEvent(e);
});
but for some reason I'm getting this error:
TypeError: Cannot read property 'addEvent' of undefined
I know the issue is that the controller not recognizing the global variable, but I don't know why. I've looked at several other posts and generally messed around with it but I can't figure out why my controllers access the service. Any ideas?

I just realized my problem, and I apologize for posting this question I am still very new to angular. My issue was very simple, I wasn't passing in the 'global' when i created my controller
myFamilyApp.controller('newEventController', [ '$scope', '$state', 'global', function (params)

Related

[JavaScript][Angular]: TypeError: Cannot read property 'getCityData' of undefined

This question has been asked many times before and I've tried the answers but they do not seem to solve the problem I'm facing. I'm new to Angular and am trying to pass a value from the controller to a factory so that I can retrieve some JSON information through an API. While I'm able to get the value from my HTML to the controller, the next step is giving me a TypeError: Cannot read property 'getCityData' of undefined. My controller code is as follows:
app.controller('MainController', ['$scope', function($scope, HttpGetter) {
var successFunction = function(data) {
$scope.data = data;
}
var errorFunction = function(data) {
console.log("Something went wrong: " + data);
}
$scope.cityName = '';
$scope.getCityName = function(city) {
$scope.cityName = city;
HttpGetter.getCityData($scope.cityName, successFunction, errorFunction);
};
}]);
The factory code is as follows:
app.factory('HttpGetter', ['$http', function($http){
return {
getCityData: function(query, successFunction, errorFunction){
return $http.get('http://api.apixu.com/v1/current.json?key=MyAppKey&q=' + query).
success(successFunction).
error(errorFunction);
}
};
}]);
I've replaced my App key with the string "MyAppKey" just to be safe but my code contains the appropriate key. Also, it would be very helpful if I could get a bit of an insight on how the function invocations happen because there seem to be a lot of function callbacks happening.
Getting undefined could be because of the service not getting properly injected.
Try:
app.controller('MainController', ['$scope', 'HttpGetter', function($scope, HttpGetter)
Also as you said, to be on safer side you aren't using the right key, but anyone using your application can get the key by checking the network calls. So, ideally, one should make a call to the backend, and backend will send a call along with the secured key to the desired API endpoint and return the response data to front-end.
Can be due to ['$scope', function($scope, HttpGetter) ?
Should be ['$scope', 'HttpGetter', function($scope, HttpGetter) instead.
You used minified version and inject only $scope not HttpGetter but used as argument in controller function that's why got HttpGetter is undefiend and error shown Cannot read property 'getCityData' of undefined
So you should inject HttpGetter in your minified version ['$scope', 'HttpGetter'
use like:
app.controller('MainController', ['$scope', 'HttpGetter', function($scope, HttpGetter)
instead of
app.controller('MainController', ['$scope', function($scope, HttpGetter)
And if your MyAppKey is secured and want to hide from user then you should use it in server side

Angular Service data not updating in $scope

I am not able to update data in my controller using the service. I want to do an http.get in my service, do some processing on the data and then update the $scope of the controller.
I have an angular service like below. From the answers I have read in the forums my data should be updating in the view. But thats not happening.
app.service('myService', function($http, $rootScope) {
this.selected = {
item: ''
}
this.getData = function(key){
return $http.get('/myapp/stocklist/'+key);
}
this.gs = [];
this.sr = [];
this.siri=[];
var vm=this;
this.cleanData = function(response){
for( var i=0; i<response.data.length; i++ ) {
vm.gs.push(response.data[i].name);
vm.sr.push(response.data[i].high);
}
vm.siri.push(vm.sr);
}
});
and here is the controller. The gs and sr variable are blanks. From what I read I dont need to use watch for this and the code below should work(I am not very clear on how to use watch as well). If this would work with watch can you please tell me how to do it.
app.controller('graph', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.mySelected = myService.selected;
console.log($scope.mySelected);
myService.getData($scope.mySelected).then(function(response){
myService.cleanData(response);
$scope.sr=myService.siri;
$scope.gs=myService.gs;
console.log(myService.sr);
});
}]);
I am new to angular and also maybe structuring the code in the wrong way. I would appreciate any design suggestions as well.
I am also wondering if I am using service in the right way for $http.get. I had asked a question earlier in the forum and this is what I had got as a reply. It works when I use the returned data from the service function and do data processing in the controller itself.
Can you please help?
Looks like you're calling the myService service again to set the sr $scope after getting a response. Instead, set $scope.sr and $scope.gs to response.siri and response.gs, respectively. Updated code below:
app.controller('graph', ['$scope', '$http', 'myService', function($scope,$http, myService) {
$scope.mySelected = myService.selected;
console.log($scope.mySelected);
myService.getData($scope.mySelected).then(function(response){
$scope.cleanData = response;
$scope.sr = response.siri;
$scope.gs = response.gs;
console.log($scope.sr);
});
}]);
Sorry this works fine. I made a mistake in making the get call. Hence not giving the correct data. Thank you for your help :)

Cannot read property 'get' of undefined and $http is not a function - Angular

I'm quite new to Angular and I'm having issues with injecting $http into the following controller:
function(){
angular.module('nps-settings-support-tools', [])
.controller('SettingsSupportToolsController', [ '$scope', 'Settings', 'gettextCatalog', '$q', '$timeout',
'$rootScope', 'SweetAlert', 'CurrentUser', '$http',
function($scope, Settings, gettextCatalog, $q, UploadFile, $timeout, $rootScope, SweetAlert, CurrentUser, $http) {
var apiUrl = '/api/v1/';
I've read here that Angular cares greatly about the order of injections, but I've double-checked that the ordering is correct. Yet, when I'm running:
$scope.doTodo = function() {
return $http.get(apiUrl + 'support?tool=digest&type=todo');
};
I get the following errors in the console:
TypeError: Cannot read property 'get' of undefined
at Scope.$scope.doDetractors
So, thinking that my memory was incorrect, I also tried with:
return $http({url: apiUrl + 'support?tool=digest&type=responses', method: 'GET'});
Which obviously fails also because $http appears to be undefined, yet I can't see where I've gone wrong, as most SO questions / answers are about ordering of injections and accessing $http via an improperly ordered injection, which I'm not doing (as far as I can see).
Does anyone know what is going on, please?
You have parameter UploadFile in the controller function, but not in the array of strings.

how to store a reference to a object or a global object with angular?

I hope the title of this question makes sense. What i need is a way of storing a reference to a object in a controller and access it in another one.
For example, i have a AppCtrl where i initiate firebase:
.controller('AppCtrl', function ($scope, $ionicModal, $timeout, $firebase) {
var ref = new Firebase("https://test.firebaseio.com/");
var sync = $firebase(ref);
$scope.db = sync.$asObject();
var authClient = new FirebaseSimpleLogin(ref, function(error, user) {
if (error) {
} else if (user) {
console.log(user);
} else {
// user is logged out
}
});
...
In another controller i want to do authClient.logout() but authClient is not available:
.controller('LogoutCtrl', function ($scope, $stateParams, $firebase) {
authClient.logout();
})
Is there a way to access authClient in the second controller without the need to instantiating FirebaseSimpleLogin, like grabbing it from a global var?
I'm not sure what is the best approach, maybe is a good idea to instantiate it again..
I'm using firebase as an example here, but this could be any other class
any ideas?
In this case angular suggests to use Services
Angular services are substitutable objects that are wired together using dependency injection (DI). You can use services to organize and share code across your app.
UPDATE
example of using simple login with firebase and angular

Angular build not working on server

I am trying to run my AngularJS front-end on server. I am using Yeoman to build the app. I upload the very basic hello world app and I get plain HTML text withou JavaScript loaded. Console in Chrome says this:
Error: Unknown provider: aProvider <- a
at Error (<anonymous>)
at http://../scripts/vendor/d10639ae.angular.js:2627:15
at Object.getService [as get] (http://../scripts/vendor/d10639ae.angular.js:2755:39)
at http://../scripts/vendor/d10639ae.angular.js:2632:45
at getService (http://../scripts/vendor/d10639ae.angular.js:2755:39)
at invoke (http://../scripts/vendor/d10639ae.angular.js:2773:13)
at Object.instantiate (http://../scripts/vendor/d10639ae.angular.js:2805:23)
at http://../scripts/vendor/d10639ae.angular.js:4620:24
at update (http://../scripts/vendor/d10639ae.angular.js:13692:26)
at http://../scripts/vendor/d10639ae.angular.js:8002:24 d10639ae.angular.js:5526
Anybody experiencing the same and knows the way out?
EDIT:
'use strict';
yoAngApp.controller('MainCtrl',['$scope', '$window', function($scope, $window) {
$scope.awesomeThings = [
'HTML5 Boilerplate',
'AngularJS',
'Testacular'
];
$scope.records = [{ title : 'one' }, { title : 'two' }, { title : 'three' }, { title : 'four' }];
$scope.greet = function() {
($window.mockWindow || $window).alert('Hello ' + $scope.name);
}
}]
);
I'm pretty sure that you have used code minifier for production server, am I right?
Anyways, the folks from Angular Js made pretty clear that using minifier can mess up Dependency Injection if it's not done properly. Why this happens? Have a look:
Dependency Injection vs. Code Minifier
function MyController($scope, $log) { ... }
In the snippet above you are making use of implicit DI. Angular sees variable $scope and tries to match it with any managed dependency. In this example it will match it to the $scope object.
This, however, will not work after code minifying, as the result will look somehow like this:
function a(b, c) { ... }
Since variable and function names were minified, Angular cannot know what exactly an "a" is.
Solution
Use explicit Dependency Injection configuration.
var MyController = function($scope, $log) { ... }
MyController.$inject = ['$scope', '$log'];
In this snippet you are defining which dependencies should be resolved by attaching array of their names to special property of controller (or service) called $inject. Now Angular will know that it should resolve $scope and pass it as first parameter to MyController. Then it will resolve $log and pass it as second parameter.
It's all possible because minifiers won't modify the contents of string variables.
As #ƁukaszBachman suggested, you may use $inject annotation or you may use Inline Annotation if you want to:
Keep your dependency annotations close to your function definitions (for better readability).
Stay away from polluting global namespace.
app.controller('UsersController',
[
'$scope', 'UserService', '$location', '$routeParams',
function($scope, User, $location, $routeParams) {
$scope.user = User.get({id: $routeParams.id});
...
}
]
);

Categories

Resources