Execute service before AngularJS bootstrap - javascript

Currently i would like to figure out, if it is possible to execute a additional service which executes an asynchronous call and bind the response in the current scope and afterwards bootstrapping my application.
I need this behavior, because i wanted to fetch some data from a server and bind this to the scope. I tried some solutions (like the resolve method in the ui-router component) but i couldn't solve it yet.
In addition i wanted to avoid to use the $watch method to observe the variable.
Anyone have a solution for this problem?
Thanks in advance.

Short of writing your own manual bootstrapping, you can't use a service before angular has been bootstrapped. But why do you need to? You can simply fetch the data after angular has bootstrapped, e.g. like Marvin Smit mentions in the comments, fetch it in your controller:
function MyCtrl($http, $scope) {
$http.get('whatever')
.then(function success(response) {
$scope.stuff = response.data
})
}
Angular's directives and interpolation are written with this in mind, and would not error if there's no $scope.stuff defined when the controller is executed.
Or you could use ngRoute/ui-router and the resolve parameter for a route(see https://docs.angularjs.org/api/ngRoute/provider/$routeProvider)

Related

Angularjs how to change $rootScope variables from UI

I'm making a dynamic web page with angular, the content from the main page should change, but to avoid writing too much code i decided to make it generic, but to know what type of content is being requested i need to send this parameter from a link/button with a ng-click, this would'nt be a problem but when i have to change the controllers i can't read the parameter.
ng-click="name='Name change'"
Here i'm trying to change a $rootScope variable named name, i tried
ng-click="$rootScope.name='Name change'"
even with a service function, but looks like doesn't work (i don't know too much about angularjs so i tried )
ng-click="$service.cambiarTipo='Name change'"
i made a plunker http://plnkr.co/edit/1BN76SbUAHuOSHs02gpL?p=preview
If you check the console log, you will see that the variable it's undefined, obviously if i change $rootScope.name from a controller i can see it from the other controller, but that's not useful since i need that feed from the user not the controller.
How i can change a rootScope variable from html?
Here'a one using a shared service between the two controller without using $rootscope at all. http://plnkr.co/edit/maKNHgVH20GxTJeCEveh
Note that ng-click is calling the service function. I'm assuming the function is for changing the name.
ng-click="service.cambiarTipo('Name change')"
You really shouldn't be using $rootScope all that much, let alone modifying it from the template. With that said, you can assign $rootScope to a $scope variable and access from the template like normal scoped variable. plunker
Controller:
$scope.rs = $rootScope
Template:
rs.name = 'Name Change'
I would like to reiterate that this is not something you should be doing as it goes against the angular way.

Notify AngularJS Controller about events from outside

New to Angular so I apologize if the question is silly.
So I'm making an app and one part of it is outside of Angular's "scope" so to speak and this part is responsible for receiving incoming messages (xmpp)
And then there is that Angular controller that has to be notified about incoming messages. What I did is an ugly work around but it works:
view.html:
<button ng-click="refreshLayout()" id="refreshLayoutButton" style="display:none"></button>
controllers.js:
.controller('chatCtrl', function($scope) {
$scope.refreshLayout = function() { ... }
})
outside.js:
if(incomingMessage) {
$("#refreshLayoutButton").click();
// append the message to view.html
}
Is there anyway to exclude jQuery? I want to send the message from outside.js to chatCtrl and then send it to view.html
OR
just notify about the event so it could invoke $scope.refreshLayout (techincally I can append incoming messages directly to view.html using jQuery without Angular, but the first option is still more preferable)
You should trigger event when there are incoming messages.
In outside.js use $broadcast when there are incoming messages.
In controller.js wait for that event to happen with $on.
Here's a simple example: http://jsfiddle.net/simpulton/XqDxG/
... technically I can append incoming messages directly to view.html using jQuery without Angular
I strongly recommend to use Angualrjs only. (For me I would remove jQuery and use only in specific cases in Directives). Angular itself includes jQuery-lite edition within it
New to Angular ...
Please follow this How do I “think in AngularJS” if I have a jQuery background? first, it will make things a bit clearer
So I hope outside.js: from your example means some Directive logic that gets event and need notify controller about.
We can listen on event into Directive and Directive can notify controller by using $eval for example. Here is basic example how $eval works: Demo Fiddle
However (for isolate scope) the other way is just to map event method. Please take a look on THIS example where Google maps notifies controller about zoom change event received.

At what stage in the angularjs lifecycle is the DOM completely loaded

I'm trying to wrap a native JavaScript functionality around an angularjs module and I need to bootstrap some code on DOMloaded event handler.
document.addEventListener("DOMContentLoaded",function(){
//bootstrapper code
})
I'm a little confused if this is needed in the angular domain or not or maybe I might just be repeating something that has already been called by angular which I could have simply attached my code to. If I put the bootstrapper code in the module's run block, will it achieve the same effect, the docs says
It is executed after all of the service have been configured and the injector has been created.
with respect to the DOMLoaded Event, has it already been fired at this time?
Anyone know anything about this?
angular.module('myApp', []).run(function($rootScope) { }); is similar to $(document).load(function() {}); in jQuery but if a part of the page is being rendered using XHR then run() method will not be helpful.
You either have to write your logic inside below event
angular.module('myApp', []).run(function($rootScope) {
$rootScope.$on('$viewContentLoaded', function() {
// here
});
});
Or you better off writing a custom directive depending upon what you have to achieve.

Bootstrap AngularJS app with data from the server

I have an AngularJS app and I'd like to pre load the $scope or $rootScope with application specific data before any of the controller code is executed. This would include stuff like roles, permissions, localizations, etc.
The only viable option I've found is to add the resolve object to EVERY one of my routes/controllers, I consider this to be a maintenance nightmare.
I also read about application.run(), however there is no way to get the dependencies from the service to resolve. Meaning you may call a service to your server in run, but it will not wait for the promise to finish before continuing on.
I feel like this is a pretty glaring problem with AngularJS.
Hopefully I'm just missing something obvious from the API.
Here is a very similar question, posted over the summer, no real solution was posted though.
AngularJS load data in app startup
Normally resolve is a good way to do if you want to do something with Angular first, then pause, then do other things with Angular.
But if you want to do something without Angular first, then start Angular, you could manually start Angular.js with angular.bootstrap. So that you can load your data first, then when you feel ready. Call angular.bootstrap() to start angular module.
What you have to prepare:
Remove ng-app="XXX" from your document.
Call angular.bootstrap() after everything is ready.
Doc for angular.bootstrap()
angular.module('myApp').controller('MYContoller', function ($scope)
{
$scope.init = function()
{
...
};
$scope.init();
}
This should work, you can also use ng-init, bit think that the docs state that you shouldn't

AngularJS: Reference to controller dynamically (by name)?

Working on a module based app where depending on the user, I'll load a given template (view) as a module inside a common view. The problem is that the different views require different controllers and they one share a small set of common form inputs.
Based on a call to my server I'll get a JSON response containing what view/controller should be loaded for that user. This solution worked fine earlier as all my controllers were in the global scope:
$scope.corporation.payloadController =
// Contains the String "ComputerPayloadCtrl"
[window]data.corporation.payloadController;
Now however, after I have rewritten the applications to use the angular module design pattern, I get the following error (I no longer use [window]):
Argument 'corporation.payloadController' is not a function, got string
The controller is already defined, so I'm only looking for a way to reference it by String.
.controller('ComputerPayloadCtrl', ['PayloadService', '$scope',
function(PayloadService, $scope) {
$scope.payload = PayloadService.payload;
}])
The more I work with this problem, the more this entire approach I've chosen is bugging me. So if anyone has any suggestions on how to alternatively solve this I'll gladly hear it.
Edit: So I found a very simple workaround, but I'll let the question stand in case there is an actual way to do this.

Categories