I need to load some parameters from Api end point before bootstrap application Angular 1.
I have a factory that contains my functions for request end point and save in memory. I need to use this factory to execute my roles. The problem is that I can not inject my facotry before bootstrap application. I can not create other roles that do the same thinks, i have to use this factory for my application working.
Anybody have a good suggestion about this case? Who already needed this case?
Thanks everyone.
If you are using the ngRoute router, you can use resolve functions to delay instantiation of the view and its controller until data arrives from an asynchronous API.
resolve - {Object.<string, Function>=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. For easier access to the resolved dependencies from the template, the resolve map will be available on the scope of the route, under $resolve (by default) or a custom name specified by the resolveAs property (see below). This can be particularly useful, when working with components as route templates.
— AngularJS ngRoute $routeProvider API Reference
I think you should be ok using the angular-ui-router. You can use resolve on your routes. This will force Angular to resolve the data before moving on to rendering the controller.
You can setup resolve before you enter your default state in ui-router.
Reference:
https://github.com/angular-ui/ui-router/wiki#resolve
Related
I have been looking at the Angular 1.5.x ComponentRouter and am trying to find a way to mimic the uiRouter resolve functionality. I have tried $routerOnActivate but it does not block the route from changing. Does anyone have the answer or a good reference to this functionality. In the docs it says "By returning a promise for the list of heroes from $routerOnActivate() we can delay the activation of the Route until the heroes have arrived successfully. This is similar to how a resolve works in ngRoute." but it does not seem to be blocking until the promise returns.
I'm trying to dynamically load a bunch of states, by merging them from some disperse files.
I'm collecting all of them with $http.get and then add all with $stateProvider.state(name, config).
All ok here.
The problem is that if I enter another URL, besides the root URL "/", that same URL is never resolved to the correct state.
It seems that, if i load the app from the root state and navigate from there, the $urlRouterProvider can match with all the loaded states, but, if i try to enter the app from a child state, for example "/#/anotherpage", it cannot match any url/state and it fallback to .otherwise('/').
It's like if it tries to resolve the URL without waiting for all the states to be loaded.
I'm using $urlRouterProvider.deferIntercept() to try to stop it from continue, and after the configuration, i just enable again the sync.
app.config(configure).run(['$urlRouter', function($urlRouter){
$urlRouter.sync();
$urlRouter.listen();
}]);
How do i make sure that $urlRouterProvider waits until all the states are loaded during .config(), and then try to match the correct state?
Thanks.
I'm not really sure that what i had is related but i'll post it : i was creating some object in a config phase. The object configuration was overridable so i couldn't built the state in the config phase of my provider. So i moved the $stateProvider calls and $urlRouterProviders calls in the $get of my provider.
If i tried to aim for one of the generated state it didn't work when loading the page the 1st time or refreshing. I had to use a "module.run(myProvider){}" to force instantiation of my provider to make it works. My guess is that my app.run was running before $urlRouterProvider resolves anything.
Another solution may be to use defer the bootstrap of your application removing ng-app and using angular.bootstrap when you're ready.
Given the code:
angular
.module('someApp', ['provider1Module, provider2Module'])
.config(function (provider1ModuleProvider, provider2ModuleProvider){
provider1ModuleProvider.getSomethingSpecific()
})
Given also that provider1ModuleProvider.getSomethingSpecific() depends on a method of provider2ModuleProvider's getSomethingGeneric() method, how can I call this method from within the config?
Right now, when I try to run code similar to this, I get an error that essentially tells me the second provider is not instantiated. Can I explicitly instantiate both providers in the config in some way so that one provider's dependency on the other is resolved?
Essentially, what I'm trying to do is get some data in an abstract view state for some views in UI-router so that I can use it in child views. If my pattern above won't work, any other suggestions?
I'm trying to integrate angularjs with dojo.
I've decided to wrap creation of dojo objects in an external module, in order to leave my controller clean.
So I have a factory that exposes creation of an AndOrReadStore instance, for example, and then in the controller I use it to instantiate my dojo store.
Here is an example of what I'm trying to do:
http://plnkr.co/edit/EM0kXKWqZzZrlISvsOik
The problem is that the assignment to the store in the controller occurs before the code inside the requirejs block gets executed (and it doesn't make any difference if the async property of dojoConfig is true or false).
How can I use a factory method that is asynchronously? Could premise solve my problem?
Thanks,
Lior
Some of my routes needs functionality from external JS. I don't want to load them all at once since those JS are needed only in certain routes (e.g. /upload needs some JS for photo uploading, /photos needs another JS for lightbox, /funny needs JS for animation stuff, etc).
What's the best practice for lazily loading those external JavaScripts?
Those routes can be accessed multiple times (e.g. user can go to /upload then /photos then /upload again)
In addition to what Alex has stated, if you will be lazy loading AngularJS artefacts such as controllers and directives, you would have to use the relevant provider to register them instead of the module API. Artefacts registered using the module API after the application has been bootstrapped, will not be available to the application. For example, you would define a lazy controller like this...
$controllerProvider.register('SomeLazyController', function($scope)
{
$scope.key = '...';
});
instead of this...
angular.module('app').controller('SomeLazyController', function($scope)
{
$scope.key = '...';
});
I have written a blog post detailing this as well as how to use the 'resolve' method that Alex speaks about, to implement lazy loading in AngularJS. http://ify.io/lazy-loading-in-angularjs/
The only way I know to handle cases like this is using the "resolve" method of a route. This method can be used to define a dependency to be loaded before the route's controller is instantiated. One of the different possible return types of this method is a promise. Thus you might use this to start loading your external JavaScript code asynchronously and return a promise that is resolved as soon as your external scripts are loaded.
The documentation for this can be found here: https://docs.angularjs.org/api/ngRoute/provider/$routeProvider in the "when" section.
#alex3683's answer is probably the correct AngularJS way, but I don't grasp the concept, so instead I make use of jQuery's getScript(). So, in CoffeeScript:
yourModule.factory 'foo', ->
$.getScript 'https://script-to-load', ->
# whatever you want to do once the script is loaded
And just call it from your controller. Since AngularJS services are lazy and singleton, this will only load the script once.