AngularJS load remote JS controller provided by webservice - angularjs

I have a AngularJS app, that depends on a webservice, I would like to load some more controllers into the app from a remote host, after the app is loaded. I don't know i this is possible?
In my controller, I want to load some more controllers (js files)
.controller('FrontpageCtrl', function($scope, $stateParams, $filter, $sce, contentService) {
console.log("hitting FrontpageCtrl ... ");
contentService.promise.then(function(data){
var page = $filter('filter')(data, {id:$stateParams.pageId})[0];
$scope.content = $sce.trustAsHtml(page.content);
// Load a controller, directive and other provided by the webservice!
$scope. ...
});
})

Currently angular does not provide a way to load modules dynamically. Hence, any angular built in object (directives, controllers, factories, etc.). This means your controllers (from the web service) should be loaded on bootsrapping angular (probably as a resource on the index page).
There are some ways to dynamically load stuff after bootstrapping, here are a few:
My personal favorite: https://github.com/ocombe/ocLazyLoad.
Closest to your question: http://weblogs.asp.net/dwahlin/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs
https://www.startersquad.com/blog/angularjs-requirejs/
There are many more stuff to be found.. you can obviously google it.

Related

When to use multiple controllers Angularjs

I'm a bit new to Angularjs. I'm confused about multiple controllers. I know Angular app can have multiple controllers. But I'm confused when to use multiple controllers. What's the advantage of having multiple controllers? Can anyone help me to clarify this? Thanks
In order to modularize your application based on the feature wise, you can have multiple controllers.
For example if you have a login feature, you can have a separate controller which does the login part(Fetching data,checking the authentication etc)
var app = angular.module('app', []);
app.controller('LoginController', function ($scope) {
//Controller Code Here which fetches the API and check authentication
});
app.controller('ProductController', function ($scope) {
//Controller Code Here which loads the products
});
For different functions we need different controllers. For example if you need a ui modal to display something then for that modal you need different controller which will handle only modal's functionality. If you try to code everything in single controller then it will be confusing for you when in future you want to edit some contents of any html page.

Configuring shared services across multiple modules in AngularJS

My app is following John Papa's styleguide for AngularJS applications:
The styleguide emphasizes using a strongly modular approach to the design of the app. My question is about multiple configurations and their effect on shared services.
Suppose I have a main module like this:
angular.module("app", ["app.feature1"])
.config(function() {
// do some configuration here
console.log("app configured");
});
And a feature module that configures a shared angular service, let's say the $http service:
angular.module("app.feature1", [])
.config(function($http) {
// configure the $http service
console.log("feature1 configured");
});
Is my understanding correct, that the configuration by "feature1" will carry over to the main module, since the $http service is a singleton and therefore shared across modules? Or do I have to configure the $http service in the main module instead, because each module has it's own $http service instance?
Edit: I can confirm that dependency configs are carried over and are executed first. See David's jsfiddle example.
As a matter of best practice, you should configure services as early as possible, which is typically your main module (the app root), and preferably only once to avoid overlapping changes.
Since $http is a singleton (as you mentioned), any changes via configuration will be propagated throughout the application every time you inject $http.
It's also worth mentioning that configuration to services is First In First Out, meaning that if you have two configuration changes, the last-accessed configuration will be the one that is persisted to the service since the previous configuration will be overwritten if they are changing identical components of the service.
In your case, yes, the change to $http in your module will be extended to your main application and any other modules using $http.
Finally, in light of the comments, child dependency configs are resolved before parent configs, as demonstrated by this simple fiddle:
http://jsfiddle.net/maqzo6fv/
HTML:
<div ng-app="app"></div>
JS:
angular.module("app", ["app.feature1"])
.config(function() {
alert('main config');
});
angular.module("app.feature1", [])
.config(function() {
alert('child config');
});
The child config will call alert before main on every load.

Using reusable models and injecting these where required in Angular

Anyone know the best recommended way of creating models in a separate JavaScript file and have these injected into the controllers that need them, rather than creating the models on fly normally in the controller?
This would make it so much easier to pass around the model and you would know exactly what you was passing around.
I have some thoughts on using Services, and inject these where I need i.e. controllers.
Controllers would then pass these onto specific services to do any heavy lifting to keep my controllers nice and light.
Is services the only and recommended way to go ? Or is there a better alternative way ?
Any use of third-party libraries / modules would also be considered.
I think services are the way to go. Not only are they injectable but they are also Singletons - meaning wherever they are injected, the same instance is shared.
Example of a service which uses the $http service to make an asynchronous call to retrieve data:
app.factory('customerService', function($http) {
var customers = [];
$http({ url: 'api/customers/all', method:'GET'}).success(function(data) {
angular.copy(data, customers);
});
return {
customers: customers
};
});
In your controller or directive, you can then inject the service and bind customers to your scope:
app.controller('ctrl', function($scope, customerService) {
$scope.customers = customerService.customers;
});
The best way to do it is by service for couple of reasons.
If you use ng-view and routing the service is not reloading and your data is safe in service
It's easy injectable to controllers
Provides two-way data binding between controllers
working plunker with two-way data binding between controllers
http://plnkr.co/edit/pt2xwlYqvY3r840tHJ92?p=preview
NOTE: if you don't have a dot in your model you are doing something wrong ;)
I believe services are the best way for this.
I have used scope inheritance to place some methods that most of my app would need at once such as a routing method I attached these to the .run () method of my main module/app.
You could separate your models into separate modules if you needed to structure your app that way.

constructor injection in angularjs

what is the correct way to do constructor injection in angularjs for instantiating objects with a factory or a service and invoke in a controller?
Ref : http://docs.angularjs.org/guide/providers
If you could provide an example it would be really helpful.
An angular service is a singleton, so whatever you attach to the execution context in the service (eg: this.*), is usable in the module it's attached to.
An angular factory is a little different. In an angular factory, you are going to want to return a handle to a factory that will run your constructor function.
Here is a plunk demonstrating both of them.
If you are writing your own angular module, your services and factories would attach to the module the same way, except, you must then inject your module into the app module.
var myAppModule = angular.module('myAppModule', ['ngRoute', 'myCustomModule'])
This will allow the myAppModule to then use all the services, factories, directives in ngRoute and myCustomModule (myCustomModule is any custom module you write and inject into your app).

The best way to Mock Services in AngularJS to decouple REST calls

I am building a web application with AngularJS and have built out a AngularJS Service that my controller uses to create, retrieve, update, delete data from. I want to farm out the UI work to another developer, but I don't want them to require the dependencies that the AngularJS Service does. I'd like to build a Mock Service and just return mock data rather than call the live REST service.
My App is set up like this:
var myApp = angular.module('myApp', ['ui.bootstrap']);
My Controller currently hooks up to the Service using:
myApp.controller('TodoCtrl', function TodoCtrl($scope, $JSOMService) {
$JSOMService.DoStuff();
});
And my Service is defined like this
myApp.service('$JSOMService', function ($q, $http) { ... });
What the are best ways to handle switching out the service for another one? This is a little different from Unit Testing and I wondered if there are any common ways of doing this?
For now I'm just having a slightly different code base where I just switch out the Angularjs Service javascript files loaded to handle this.
You can get access directly to the provider service, which controls injections. It would look something like this, where $provide is injected:
$provide.value('$JSOMService', MockJSOMService());
This will basically say, whenever someone asks for $JSOMService, give them whatever was returned from MockJSOMService.
You can set this up at the when you set up your app. Like this:
myApp.run(['$provide', function($provide) {
$provide.value('$JSOMService', MockJSOMService());
}]);
This is basically how you could switch out services. Admittedly a little funky, but I hope this helps!

Resources