.config() of AngularJS - javascript

I am new in AngularJS. I am learning AngularJS. In this regard I found below syntax in a tutorial.
app.config(['$routeProvider',function($routeProvider){}]);
Here .config() is a method. I am passing an array as parameter of this .config() method. '$routeProvider' and a anonymous function are two elements of that array. Am I right ??
Can I make any change of the first element of the array, like '$routeProvid' or '$routeProvideraa' or '$outeProvider'??
Can I make any change of the second element of the array, like function($routeProv) or function($routeProviraa) or function($outeProvi)??
Thanks
UPDATE
I think I failed to express. I am updating the question
Can I use below syntax??
app.config(['$routeProvid',function($routeProvider){}]);
or
app.config(['$routeProvider',function($routeProv){}]);
or
app.config(['$teProvider',function($routeProvi){}]);
Did you get this portion ??
.config() is a method. I am passing an array as parameter to this .config() method. '$routeProvider' and a anonymous function are two elements of that array.

AngularJS uses the parameter name for dependency injection; once minified the variant without the array would break.
Since strings aren't modified during minification they are used to map to their parameters. So to answer your question if you use the inline array annotation you can change the arguments to whatever you want. If you don't rename the strings or change the order of the dependencies you should be fine.

this is the annotation in AngularJS...
Basically, AngularJS provides a very useful Dependency Injection system that allows to retrieve dependencies simply declaring them as function parameters...
So, if you register something through the angular recipes, then, you are able to retrieve them in this way:
angular
.module('test', [])
.value('myValue', 'Hello World')
;
angular
.module('test')
.run(function(myValue) {
console.log(myValue);
})
;
This is very useful because allows scalability, testability, ecc... but creates one problem: It cannot be minified
The $injector cannot understand the result of the minification, because function parameters are mangled and the above code becomes:
angular.module('test').run(function(a) {console.log(a);})
So, the only way to minify angularjs code is to annotate each dependency that must be injected.
Annotation can be made in two ways:
via $inject property
using the array-like annotation
Your code belong to the second case, basically, instead of passing the function directly, you can pass a javascript array that has a function in the last index position:
[function() {}]
the above example becomes:
angular.module('test').run(['myValue', function(a) {console.log(a);}]);
There are many build tools that perform automatic annotation (ng-annotate), and is always suggested run the angularjs in strict-di mode.
Hope it helps

The first n elements of the array are factory names and you should use something that is registered at this point. Here - router - which has its own provider (the thing that can setup the router service). The config itself hasn't got too many options to choose from as it is parsed before your app is instantinated, hence you'll use providers and constants here. https://docs.angularjs.org/guide/providers
The last element of the array is the function whose arguments should correspond to the things you pass in the array. The names here are your choice, although keep in mind the order.
So, summing up, you can't rename the thingies in the quotation marks '$routeProvider', instead, know your app and what you are installing. But you can use your own names for them in the latter function($mynameforrouteprovider) but you have to keep them in order. Best if you use the same names that their author uses.

Related

AngularJS Directives: ngModelCtrl.$parsers

After looking at a few different custom directives, I have noticed that some people use ngModelCtrl.$parsers.push() and some others use ngModel.$parsers.unshift(). Could someone explain the difference.
push() adds to the end of an array.
unshift() places the new element at the front of the array.
The order matters because parsers are executed in order. From the Angular docs:
Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. The functions are called in array order, each passing its return value through to the next. The last return value is forwarded to the $validators collection.
$parsers.unshift() put your parser function in the beginning of the list, so it will be executed before all the other, $parsers.push() put it in the end.
$parsers it is an array object and provides array functions

Ember GroupableMixin by using groupProperty

I am trying to implement GroupableMixin (https://github.com/ahawkins/ember.js/blob/groupable-mixin/packages/ember-runtime/lib/mixins/groupable.js) on EmberJS but I have trouble using it.
I want to specify a groupProperty in my ArrayController (just like how we have sortProperties) and I want my groupings to be calculated based on that property.
I did try http://emberjs.jsbin.com/cawaq/3/edit and this is what I got:
App.UsersIndexController = Ember.ArrayController.extend({
sortProperties: ['created_at'],
groupProperty: 'role',
groupedContent: groupBy('role'), //How do it reference groupProperty in groupBy?
//How can groupedContent be updated whenever groupProperty is changed?
});
I have seen http://discuss.emberjs.com/t/ember-enumerable-no-group-by/3594/6 and http://jsbin.com/ukagip/2/edit but still cannot quite figure out how to make that work properly.
The intent and behavior of Mr. Hawkins' GroupableMixin is very different from the one that's used discussed in Ember's Discourse forum. It seems that you're confusing the two methods.
Mixin Approach (a la Mr. Hawkins)
Note this is the approach I'd recommend
The GroupableMixin is an instance of Ember.Mixin, which is used to extend an object's prototype. For a more in depth explanation of mix-in's see Coding Value's explanation.
We can determine the mix-ins requirements and behavior from reading the tests for the mix-in:
the class must behave like an ArrayProxy (so ArrayController's are fine)
a groupBy property must be set for the class
So we can include this mix-in in an array controller as follows:
App.UsersIndexController = Ember.ArrayController.extend(Ember.GroupableMixin, {
groupBy: 'role'
});
Now that we've satisfied the mix-in's requirements, we'll have access to a few new computed properties and functions such as groupedContent for free. Without adding anything else to the controller, we could write something like this in the template to access the groups:
{{#each group in groupedContent}}
<h1>{{group.name}}</h1>
<ul>
{{#each user in content}}
<li>{{user.name}}</li>
{{/each}}
</ul>
{{/each}}
Here's an example that groups words in an array controller by first letter.
Computed Helper Approach (a la Ember Sherpa)
This method creates a helper which defines a computed property based on the key provided to the function. We can create a similar function which maps to the group interface of the mix-in:
Sherpa = {};
Sherpa.groupBy = function (groupBy) {
var dependentKey = 'content.#each.' + groupBy;
return Ember.computed(dependentKey, function(){
var result = [];
this.get('content').forEach(function(item){
var hasGroup = !!result.findBy('name', get(item, groupBy));
if (!hasGroup) {
result.pushObject(Ember.Object.create({
name: get(item, groupBy),
content: []
}));
}
result.findBy('name', get(item, groupBy)).get('content').pushObject(item);
});
return result;
});
};
Now we can use this function to create a groupedContent computed property: groupedContent: Sherpa.groupBy('role')
Here's an example which uses the same template as the previous example and has only swapped the mix-in with this method.
Recommendation
Use the GroupableMixin, it's far more robust than the method discussed in the forum:
The method discussed in the forum...
is simple and easy to understand
is inefficient
Recomputes the entire groups array whenever a change is made to the array or relevant property
Doesn't implement map structures for lookups and instead searches iteratively through the array
Nukes all itemControllers on any computed change: If you check some boxes in the second example and then add a new word, all of the checkboxes will be cleared
The mix-in...
is a much more robust, albeit complex, implementation
handles inserts and removals to groups instead of recomputing the entire map
backs the groups with a map for better performance and efficiency
behaves as expected when using an itemController: just tick of checkboxes and add some words in the first example, and you'll notice that the checkboxes are never cleared

Ember.js - Controller functions with observed properties don't execute when the function name changes

I’m using the new query params feature http://emberjs.com/guides/routing/query-params/ and trying to figure out an issue when using .property().
In the client side sorting example when I change the name of the methods sortProperties, or paged (I’ve added console output to each) they no longer execute when their observed property changes. The name of the method shouldn’t matter right?
http://jsbin.com/ucanam/5069/edit
You can't rename sortProperties, it's property of Ember.SortableMixin
In your example computed property sets sortProperties: [resultOfComutedProperty] and if you'll rename sortProperties will no reasons to fire it.
paged is just computed property, don't forget to rename it in handlebars template and all will work

Getting ember-i18n.js Translation Keys from Controller Properties

I just started working on an existing Ember.js project that uses ember-i18n.js for localization.
Ember.Mixin.create({
setupController: function (controller, model) {
controller.set("somePropertyName", "my.translation.key");
}
});
I defined another helper that lets me get a translation key from a context property, instead of passing it in directly, e.g. I can use {{tr someContext.someProperty}} instead of {{t "my.translation.key"}}.
Ember.Handlebars.registerBoundHelper('tr', function(property, options) {
return Ember.I18n.t(property);
});
I'm fairly new to Ember, so my thought process was that I would simply be able to swap out replace {{somePropertyName}} in my template with {{tr somePropertyName}}. That didn't work. When I set a breakpoint inside the helper, I see that property is always undefined.
I also tried modifying my helper to use Ember.Handlebars.get() as demonstrated here, but that also is resolved undefined.
Assuming I'm not able to change where the translation key is coming from, is there a proper way to get the translation key from the controller to the helper?
What you are doing should be fine - the property argument to the helper is just a string, and passing a string from a controller to a template (and then to a helper) is straightforward.
So, I'm guessing (and it's just a guess without a jsbin) that either you have a coding issue somewhere. Or something weird is going on with your use of the mixin, perhaps.
I'd see how far the string property is getting from your mixin to the controller to the template to the helper.
If you change {{tr property}} does the string get written out into your template ok? If not, then the property isn't being set on your controller.
If you have a jsbin, then that would make it easier to see what is going on.

What does template.data._id do in Meteor?

Beginner Meteor/JS question:
When associating objects in Meteor I see small line of code that I'm not understanding. For example, post with associated comments.
var $body = $(e.target).find('[name=body]');
var comment = {
body: $body.val(),
postId: template.data._id
};
So get the content of the comment, put it in the variable "comment", and also create a postId to go into this comment so you know what post the comment belongs to. This postId is being called in with *'template.data._id'*
My questions are:
So you call template, then wouldn't you want to call the template name? Not data? Where is data coming from?
That aside, so you call data...and then ._id, are there other options to 'data'? IE
template.data.(option)
This isn't working for me, haha, *console.log(template.data._id);* is coming back undefined. So it's not grabbing the object ID as advertised. I'm sure I messed something up.
Here's the surrounding code if you need more context:
https://github.com/DiscoverMeteor/Microscope/blob/master/client/views/comments/comment_submit.js
Beginning with the easiest first, under your point 3 it should read:
console.log(template.data._id);
As to points 1 and 2, the key idea to note is that your code is being called inside of Template.commentSubmit.events({}). Inside of this object (the "{}"), you are working with an instance of the template in the document, including whatever data is being passed to that instance. In a different template, you will receive different data and hence template.data will consist of different keys and values. You can check out more in the documentation here, http://docs.meteor.com/#template_inst.
So in answer to your question, the reason you can invoke "data" rather than the template name is that the template name has already been provided by Template.commentSubmit. Note that inside of events({}), "this" will generally be equivalent to "template.data." So
console.log(template.data._id);
will generally be equivalent to
console.log(this._id);
The properties you can access on the data will always vary based on the instance received by the template. For example, if template.data consists of {_id: 1, name: "x", location: "y"}, you can retrieve these values by calling the keys, e.g. "template.data.name" or "template.data._id" etc. In your example, you are correct that you are setting postID to template.data._id.
The data arriving to the template comes from your Meteor.subscriptions. Hope this helps.
The template has a data context. When you use an {{#each}} block you are iterating through data, in this case posts.
So using template.data retrieves the data context for the template. It would refer to a post from where the comment form is. So template.data._id is the equivalent of this post._id (where post is the post you're commenting on).
The thing is I think this was removed from meteor. It was there a couple of versions back. I'm not sure about this but that's what I thought. I would have thought the correct code should be this._id. Where this ends up being the data context of the form (which would again be the post).
Could you check if that gives you undefined if you changed it out?
The .events method of a template takes in an event map:
http://docs.meteor.com/#eventmaps
The callbacks for each of the events (in this case 'submit form') can take two arguments. The first one 'e' is the javascript event object and the second one 'template' is the instance of the template where the event occurred. That template instance has a bunch of utility methods/properties (see http://docs.meteor.com/#template_inst) one of which is .data (see http://docs.meteor.com/#template_data). That .data property returns the data that the template was bound to (in your Microscope example it looks like it's bound to a comment object) and that object (in this case) has an _id property.
Note that the 'template' (little T) is not the same as Template (big T).

Categories

Resources