AngularJS init firing twice - angularjs

I have the following code for AngularJS. Within is a checkStatus function that invokes a web api to check a status of a user's PC. The problem I'm having is that the checkStatus() function is firing twice and hitting the back-end service twice. I do not understand why.
<script>
(function() {
var pageApp = angular.module('pageApp', ['commandAPI']);
function PageCtrl ($scope, $http, commandAPI) {
$scope.checkStatus();
}
angular
.module('pageApp')
.controller('pageAppCtrl', PageCtrl);
})();
</script>

Well it seems that somehow the properties of the app and the controller were applied to two HTML elements within the page. Not sure how that happened but there it was.

Related

Can't set angular $scope variable from a callback function in Ionic

I am new in angular js. I am working with web Sql in a test project for learning purpose. My insert operation is working fine. My problem is when i fetch all the records then i can't store it in $scope.todos=results.rows
My code is
tx.transaction(sql,[],myCallback)
function myCallback(tx,results)
{
console.log(results.rows); // shows objects in console
$scope.todos=results.rows;
}
In view the todos is not working with ng-repeat.
It might help to show all of your controller, or service. If it's a controller make sure you included the $scope parameter for example:
.controller('MyController', function ($scope){
}))
If you are doing this inside a service, save it in a variable inside the service, then from a controller where the "$scope" is available include your service then call your variable containing the results. This will also be helpful if you need to share those results with other controllers at a later time.
.service('MyDataService',function(){
var todos;
return {
.... set and get functions to access variable ...
getTodos: function() {
return todos;
}
};
});
And in controller
.controller('MyController', function ($scope, MyDataService){
$scope.todos = MyDataService.getTodos()
}))
There are also ways to get the $scope working in a service but I don't think it's a great idea.

AngularJS - Running a function once on load

I am trying to run an $http function when my AngularJS application first loads.
This $http function needs to finish before any of the controllers in my application could properly function. How would I go about doing this? This sounds like a promise, but it sounds like I would be creating a promise in each controller...
I currently have the function that I want to run first like this:
app.run(function() {
$http.get('link').success(function(data) {
// success function. The data that I get from this HTTP call will be saved to a service.
}).error(function(error) {
});
});
However, sometimes the controller will load before the http call finishes.
The problem
Angular is not dynamic, you cannot add controller dynamically neither factory, etc. Also you cannot defer controller bootstrap, angular loads everything together, and it's quite disadvantage (will be fixed in Angular 2)
The cure
But javascript itself has very important feature - closure, which works anywhere, anytime.
And angular has some internal services that can be injected outside of angular ecosystem, even into browser console. Those services injected as shown below. We technically could use anything else (jQuery.ajax, window.fetch, or even with XMLHttpRequest), but let's stick with total angular solution
var $http_injected = angular.injector(["ng"]).get("$http");
The act
First of all, we defer whole angular app bootstrap, inject http service. Then you make your needed request, receive data and then closure get's to work, we pass received data into some service, or we could also assign in to some angular.constant or angular.value but let's just make demo with angular.service, so when your service has data, bootstrap whole app, so that all controllers get initialized with your needed data
Basically that kind of tasks solved like this
<body>
<div ng-controller="Controller1">
<b>Controller1</b>
{{text}}
{{setting.data.name}}
</div>
<hr>
<div ng-controller="Controller2">
<b>Controller2</b>
{{text}}
{{setting.data.name}}
</div>
<script>
//define preloader
var $http_injected = angular.injector(["ng"]).get("$http");
$http_injected.get('http://jsonplaceholder.typicode.com/users/1').then(function(successResponse) {
//define app
angular.module('app', []);
//define test controllers
//note, usually we see 'controller1 loaded' text before 'settings applied', because controller initialized with this data, but in this demo, we will not see 'controller1 loaded' text, as we use closure to assign data, so it's instantly changed
angular.module('app').controller('Controller1', function($scope, AppSetting) {
$scope.text = 'controller1 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
angular.module('app').controller('Controller2', function($scope, AppSetting) {
$scope.text = 'controller2 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
//define test services, note we assign it here, it's possible
//because of javascript awesomeness (closure)
angular.module('app').service('AppSetting', function() {
this.setting = successResponse;
});
//bootstrap app, we cannot use ng-app, as it loads app instantly
//but we bootstrap it manually when you settings come
angular.bootstrap(document.body, ['app']);
});
</script>
</body>
Plunker demo
You can do this when you configure your routes
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainCtrl',
templateUrl: 'main.html',
resolve: {
data: ['$http',
function($http)
{
return $http.get('/api/data').then(
function success(response) { return response.data.rows[0]; },
function error(reason) { return false; }
);
}
]
}
});
}]);
Similar question:
AngularJS - routeProvider resolve calling a service method
AngularJS: $routeProvider when resolve $http returns response obj instead of my obj
Heres a plunkr I found using a service, which is what I would recommend.
http://plnkr.co/edit/XKGC1h?p=info

A code is being called more than once inside of a controller in Angular Js

I have the following code in Angular Js
moduel.js
var app = angular.module('myApp', []);
Controller
app.controller('myCtrl', function($scope)
{
alert("Hellow World");
//Some code....
});
The above alert box is getting displayed more than once. I am able to see this 4-5 times when I run the above code.
So i tried to place the same code in document.ready function inside the controller...
angular.element(document)
.ready(function ()
{
});
But still I am able to see alert displaying more than once in the page.
I heard the reasons for this could be $watch on which I don't have any idea.
Actually i have a very big function, which is being called more than once. For simplifying this I added alert() box instead of function. then I came to know that default variables, alert() boxes and function calls are triggering more than once in the page.

How to call JS function outside from AngularJS app?

I have JS file with simple function on clear JS:
function Alert(){
alert();
}
In another file I have application on Angular JS.
At first connected simple JS file on page and after Angular JS on tags <head>
How I can call Alert() method from controller Angular JS?
Simple JS file:
$(function(){
function leftTimeInit(){
$.each($('.action-loader'), function(index, val) {
initLoader($(this), $(this).data('percentage'));
});
}
});
Angular JS in controller:
leftTimeInit();
I get error:
Uncaught ReferenceError: leftTimeInit is not defined
You shouldn't do DOM manipulations in your controllers. So you should probably rethink how you want to use that function.
Anyway, leftTimeInit is declared in an anonymous function, and only visible there. You can't call it anywhere else. If you want that, you'll have to move it out of $(function(){}) . But as I've said, not recommended.
As for your Alert() example... In Angular you have access to simple JS global functions via $window (of course, they're global and you could access them anyway, but if you use $window you can mock them in tests).
.controller('Ctrl', function ($scope, $window) {
$window.Alert('something');
});

AngularJS and google cloud endpoint: walk through needed

I'm new to AngularJS but I really like the way AngularJS works so I want to deployed it as client side for my Google cloud endpoint backend. Then I immediately get two problems:
1, Where to put the myCallback, so it's able to work into the ANgularJs controller?
<script src="https://apis.google.com/js/client.js?onload=myCallback"></script>
2, How I'm able to do the oauth2? and how the controller knows if the user authorized?
gapi.auth.authorize({client_id: myCLIENT_ID,
scope: mySCOPES,.....
Any help is appreciated.
For loading Google Javascript Library with AngularJs, the callback function passed to onLoad of Google Javascript Library is the function that bootstrap AngularJS, like this:
This goes to the final of html file:
<script src="https://apis.google.com/js/client.js?onload=startApp">
Then, in <head> section you bootstrap angular like this:
<script type='text/javascript'>
function startApp() {
var ROOT = 'http://<yourapi>.appspot.com/_ah/api';
gapi.client.load('myapifromgoogleendpoint', 'version1', function() {
angular.bootstrap(document, ["myModule"]);
}, ROOT);
}
</script>
As described by Kenji, you also need to remove ng-app directive from your html.
Regarding the callback - In order to access an Angular controller you need to use an injector (http://docs.angularjs.org/api/AUTO.$injector)
Simply create a global callback function, and then get reference to the controller from it like this:
window.callbackFunction() {
injector = angular.element(document.getElementById('YourController')).injector()
injector.invoke(function ($rootScope, $compile, $document) {
$rootScope.variable = "stuff you want to inject";
})
}
In this example I'm injecting the data to the rootScope, but this will also work for a specific controller scope (just inject $scope instead)
Can't help with the second question as I'm not familiar with gapi, though making auth2 calls from angularjs is quite straight forward.
Here you have details on how to use angularjs with google endpoints:
https://cloud.google.com/developers/articles/angularjs-cloud-endpoints-recipe-for-building-modern-web-applications?hl=es

Resources