What is AngularPublic.js? - angularjs

If I wanted to add my own custom "provider" to the list (in AngularPublic.js), like so:
...
$provide.provider({
$anchorScroll: $AnchorScrollProvider,
$animate: $AnimateProvider,
$browser: $BrowserProvider,
$cacheFactory: $CacheFactoryProvider,
$controller: $ControllerProvider,
$myCustomController: $MyCustomControllerProvider, <---- I made this
$document: $DocumentProvider,
$exceptionHandler: $ExceptionHandlerProvider,
$filter: $FilterProvider,
$interpolate: $InterpolateProvider,
...etc
If I used an existing provider as boilerplate, would this be a bad idea?

Yes, it is definitely a bad idea. I don't think it is reasonable to modify the source code of Angular as Angular itself is fast growing, things change every second, you may find it is hard to merge your change with newest Angular version one day.
If you only want to add your custom provider into ngModule, you can just to this.
var ngModule = angular.module('ng');
ngModule.provider('myCustom', function() {
// Your code goes here
});
Hope it may help you.

Related

angularjs - implement route's resolve feature without routing/ng-view

In a big application, i now need to access some data (json api call) from asynchronously (before, those data were accessed synchronously).
I would like not to have to change components implementation to now handle this async behaviour (too risky).
I thought about $routeProvider's "resolve" feature (with promises) that helps to abstract this async behaviour out from the components/controllers.
Unfortunately i am absolutely not using routing in any way.
Is there an implementation for that? If not, where could i start?
EDIT:
how i was before (jsonData were not loaded synchronously but it was transparent thanks to systemJS features, SystemJS, Which we are throwing in garbage now, hence the question):
https://plnkr.co/edit/BSreVYNAr7sijYwEpb5G?p=preview
How i am now:
https://plnkr.co/edit/WnX0ynOqkZsmEzIxl1SI?p=preview
Watch the console to see an example of the problems that can occur now.
I kind of made it work by going like that, but i'm not completely satisfied with it (watch the config block):
https://plnkr.co/edit/P9Rv6rnboFlaFZ0OARNG?p=preview
$provide.value('$provide', $provide);
$routeProvider.otherwise({
template: '<test></test>',
controller: function ($provide, myJsonData1) {
$provide.value('myJsonData', myJsonData1);
},
resolve: {
myJsonData1: function(){
return getMyJsonData();
}
}
});
Hope this helps :)

Define global variable with Typescript Angularjs in components

My application uses components and boostrapper. I want to create a datepicker which will set a global date variable. I have tried to create a service, use the rootscope and basically all the solutions I could find on stackoverflow but it doesn't seem to work.
What would be the correct approach to create a global variable shared across all components?
It's generally not a great idea to use a global variable to store state like this, as it's hard to track what is mutating it.
Assuming Angular 1.x, to share information like this, you can simply create a service which stores whatever data you are tracking. I'll add the disclaimer here that state management in web apps is still a tricky problem. You could go for a Redux styled approach, but I'll keep it basic for now.
angular
.module('app', [])
.controller('testController', function(testService) {
console.log(testService.getDate());
});
angular.module('app')
.service('testService', function() {
var date = new Date();
function getDate() {
return date;
}
function setDate(newDate) {
date = newDate;
}
});
This way, you have an interface to read/mutate the date. You can inject it into as many controllers/components as you like.
Hope that helps (I'm aware the answer isn't in Typescript, but I assume since the problem has a basic solution, it doesn't matter too much - if you want a Typescript answer, let me know and I'll change it for you :) ).

Override the System package in mean.io

Q1) I need help with overriding System package in mean.io? I am trying to create my own home page.
So I did this
angular.module('mean.mysystem', ['mean.system'])
.config(['$viewPathProvider',
function($viewPathProvider) {
$viewPathProvider.override('system/views/index.html', 'mysystem/views/index.html');
}
]);
I get following error http://errors.angularjs.org/1.3.2/ng/areq?p0=MysystemController&p1=not+aNaNunction%2C+got+undefined
Can anyone suggest a resolution or a better way to do this?
Q2) Also, is this the right way to extend a package
Mysystem.register(function(app, auth, database, System) {
Does mean know the package to extend from a variable name?
Don't know why, but removing the ['mean.system'] worked for me. Something as below,
angular.module('mean.mysystem')
.config(['$viewPathProvider',
function($viewPathProvider) {
$viewPathProvider.override('system/views/index.html', 'mysystem/views/index.html');
}
]);
This might be the why: "angular.module('mean.mysystem', ['mean.system'])" creates a new module which probably is in conflict with the one MEAN creates during package registration.
Creation versus Retrieval
Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.
See detail # https://docs.angularjs.org/guide/module
Angular Modules and Dependencies
Every package registration automatically creates a corresponding angular module of the form mean.[package-name]
See detail # https://github.com/linnovate/mean#angular-modules-and-dependencies
You can just add:
$stateProvider
.state('/', {
url: '/',
templateUrl: 'youPackage/views/index.html'
});
into your routes file.
$viewPathProvider not exist in older version of mean.io, for example in this used by openshift quickstart.

Angular translate extend existing translations

I am trying to have external modules change my $translateProvider.translation on the main module. see this as a "tranlation plugin" for my app.
it seems like changing translations from the $translate service is not possible.
mymodule.service('MyService', function ($translateProvider) {
var lib = function () {
//EDITED FOR BREVITY
this._registerTranslations = function (ctrl) {
if (!ctrl.i18n) return;
for (var name in ctrl.i18n) {
/////////////////////////////
// THIS IS THE PLACE, OBVIOUSLY PROVIDER IS NOT AVAILABLE!!!!
$translateProvider.translations(name, ctrl.i18n[name]);
//////////////////////////////
}
};
//EDITED FOR BREVITY
};
return new lib();
});
anyone with a bright idea?
So, to answer your question: there's no way to extend existing translations during runtime with $translate service without using asynchronous loading. I wonder why you want to do that anyway, because adding translations in such a way means that they are already there (otherwise you would obviously use asynchronous loading).
Have a look at the Asynchronous loading page. You can create a factory that will load a translation from wherever you want.
I created an Angular constant to hold new translations. If I want to add a new translation, I add it to the constant. Then in my custom loader, I first check the constant to see if the translation exists (either a new one, or an updated one). If so, I load it from the constant. If not, I load it from a .json file (or wherever you load your initial translations from). Use $translate.refresh() to force translations to be reloaded and reevaluated.
Demo here
The demo is pretty simple. You would need to do a little more work if you wanted to just change a subset of the translations, but you get the general idea.
From the AngularJS docs (https://docs.angularjs.org/guide/providers):
You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications.
Providers are to be used with the application's .config function. $translateProvider for configuration, $translate for other services and controllers.

How to create generic controllers in AngularJS?

I am looking for advice with regards to creating a generic controller which I can reuse in my application. As an example I have created the following GIST:
https://gist.github.com/heide-de/10832576
but here is the relevant code snippet:
angular.module('genericTestApp', [])
.factory('Names', function() {
return {
names: []
};
})
.controller('IndexController', function(Names) {
Names.names = [
{firstname:'Sarah', surname:'Schmitt'},
{firstname:'Paul', surname:'Wells'},
{firstname:'Felix', surname:'the cat'}
]
})
.controller('SecondIndexController', function(Names) {
Names.names = [
{firstname:'Octo', surname:'Cat'},
{firstname:'Beth', surname:'Appleby'},
{firstname:'Fred', surname:'Bloggs'}
]
})
.controller('TableController', function($scope, Names) {
$scope.names = Names.names;
})
What feels very wrong to me is that the TableController in this example relies on the fact that the injected Names factory needs to have been configured previously in the IndexController.
The next developer that comes along will just inject Names, and will have no idea that it needs configuring prior to that.
Is there a better way of doing this with Angular?
You're right in your approach – Configuring a factory in a controller is always a bad idea. A controller is supposed to contain view specific logic, and in my opinion should even only be included when that particular view is rendered. (that's how I write my apps anyway)
To configure anything when the application loads up, you need run, that should contain all the initial stuff that your app needs to do in the beginning.
This might be a good read.

Resources