Difference between event and $event [duplicate] - javascript

Does anyone know if the reasoning behind the use of dollar methods and variables in angularJS is to instruct angularJS to avoid checking those values when a digestion is going on? So, if angular comes across $scope.$value and $scope.value, then it will avoid checking the former since it's prefixed with a dollar character in its variable name?

It is just a naming convention from the below snippet
http://docs.angularjs.org/tutorial/step_05
'$' Prefix Naming Convention
You can create your own services, and in
fact we will do exactly that in step 11. As a naming convention,
angular's built-in services, Scope methods and a few other angular
APIs have a '$' prefix in front of the name. Don't use a '$' prefix
when naming your services and models, in order to avoid any possible
naming collisions.
http://docs.angularjs.org/guide/concepts#angular_namespace
Angular Namespace
To prevent accidental name collision, Angular
prefixes names of objects which could potentially collide with $.
Please do not use the $ prefix in your code as it may accidentally
collide with Angular code.

There are a few times Angular ignores variables prefixed with the dollar sign:
In Schumli's comment below, where json filters will not output them
When using the {{ }} directive, angular will not show nested $
variables. For example this only displays the visible property.
<div ng-init="n = { visible: 'foo', $ignore: 'bar' };">{{ n }}</div>
Additionally when adding an explicit watcher on a scope object, changes to properties with a leading dollar sign of this object will not trigger the watcher. See this updated fiddle.
angular.equals() ignores keys prefixed with $.

The $ prefix denotes a variable, parameter, property, or method that belongs to the core of Angular.
Properties on objects that originate inside the framework, but are not actually part of the API, may begin with $ – or even $$ – to denote a private method or property. This is the same way the _ prefix is often used in other libraries.
It doesn't have any effect on the way code is interpreted by the runtime, although the framework itself may give it special meaning. Basically, it is a naming convention that says "You shouldn't mess with this".

Not completely sure, but I believe AngularJS internals rely on manipulating these $-prefixed variables during the digest. Checking these variables would mean that the digest would never stabilize, since they may constantly change during each cycle of the digest.
Don't quote me on it though. :)

Dollar ($) signs also prevent elements from being iterated (or interpreted) in certain directives.
So for example properties that start with $ are not used in ng-repeat because of an if clause in the for loop:
if(collection.hasOwnProperty(key) && key.charAt(0) != '$')
Someone made an issue about the topic here on angulars github page
In the method shallowCopy properties that start with $$ are skipped because of an if clause while iterating the properies:
if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {

I always figured $ looks like an "S" for service.

#MarcoS provided the link to https://thinkster.io/a-better-way-to-learn-angularjs/scope-vs-scope which explains a difference between $scope and scope. I found this useful, adding to the information in other answers.
In an angular directive there is a link and controller. The link is a standard function with a fixed set of parameters: scope, element, attributes object.
The controller's arguments are managed by the Angular injector and are not order dependent. The injector resolves which objects to pass in by looking for the parameters starting with $.
The author of https://thinkster.io/a-better-way-to-learn-angularjs/scope-vs-scope does a better job of explaining it.

There's a huge difference, not in variables, but in the parameters that a controller receives. A scope parameter is completely different from a $scope one.
For more information, check out this useful post: http://www.thinkster.io/angularjs/aw9kWmdnik/angularjs-scope-vs-scope

Related

$ sign in JavaScript function

I've found some weird for me function in the project that I'm currently working on:
Building.Widget.ClientIdV2 = function Building$Widget$ClientIdV2() {
...
What does $ mean here and what does the "name" of this function mean (Building$Widget$ClientIdV2) ? I've seen also ... = function () { code so far..
Thank you.
The dollar sign has no special significance. It is just a character you can use in an identifier.
The name of the function can be used to refer to the function from inside its own scope (which can be useful for recursive functions) and will appear in useful places like stack traces.
$ is just another character you can use in an identifier, it has no intrinsic special meaning. It could be Q or _ just as easily.
In that particular example, the original author is naming the function in a way that they can readily see that it's the ClientIdV2 function on the Widget object on the Building object. But that's just the author's convention. That's useful for looking at call stacks and such.
It looks like it's someones naming convention. You can preety much put anything that you want in Javascript variable names. You should try finding general naming conventions in Javascript in case that you're interested in that(it will make your work with other developers much easier).
For example, some people like to put the $ before jQuery variables, implying that they can chain functions on that selection.
In Javascript it's completely valid to use $ in names, just like letters or underscores, so syntactically it means nothing special. Thought it's frequently used to give extra semantic meaning to names, for eg. it may indicate that a variable is special to a system (internal variable, global, etc.). In your case I believe $ indicates object hierarchy. The use of $ is just conventional.

How can I differentiate between $ (jQuery) and $scope from AngularJS?

In jQuery, we do DOM Manipulation like,
$(this).hide();
whereas in AngularJS , we have the scope of the controller using which we can do a lot.
$(scope).somevar=somevalue;
Can we compare these two different Javascript Objects?
$(scope) is not proper angular syntax AFAIK. The dollar sign $ in JS is not a special character. it can be part of a variable like a lot of other symbols.
There is no conflict natively between jQuery's $ and angular's $scope, $resource, $q etc. They're different variables, just like j, jscope, jresource, jq would be different variables.
As for comparing these values, you're in a severe case of apples to oranges. jQuery-wrapped DOM elements may be comparable to arbitrary values in your scope but you'd have to determine some meaningful way to perform that comparison.

Symbol.for(string) in ECMAScript 6

It took me a while but I finally figured out what the purpose of symbols in ECMAScript 6 is: avoiding name collision when attaching properties to shared objects - HTML elements e.g. (In case you're stuck on the same question, I recommend this article.)
But then I stumbled upon Symbol.for(). Apparently ECMAScript 6 will maintain a global symbol registry which you can query with this function by providing the symbol description. Come again? If I use symbols to avoid name collisions, why would I want code other than my own to use them? (*) And how would I avoid name collisions in that global registry? Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
(*) Yes, I know symbols aren't truly private, but that's besides the point.
If you don't want your symbols to be available in GlobalSymbolRegistry, just don't use Symbol.for.
Only use it if you want to allow other codes to use your symbol.
In the following example, I create a symbol to store data in DOM elements. And I may want every other code (e.g. internal raw uncompiled handlers) to read that data. So I make the symbol globally available.
var sym = Symbol.for('storeDataInDOM');
document.querySelector('button')[sym] = 'Hello, world!';
<button onclick="alert(this[Symbol.for('storeDataInDOM')])">Click me</button>
It's like creating global variables: should be avoided in general, but has its advantages. But with symbols instead of strings.
If I use symbols to avoid name collisions, why would I want code other than my own to use them?
That's not the only use case of symbols. The two most important other ones are:
they don't collide with string-keyed properties
they are not enumerated by the usual mechanics
Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
Not necessarily. Right from that article you read: "The registry is useful when multiple web pages, or multiple modules within the same web page, need to share a symbol." The best example for these are the intrinsic symbols - they guarantee interoperability across realms, that's why the global symbol registry is more global than your global scope.
For example you might have a library that is loaded in a web page, an iframe and a web worker. If you share data between those environments (realms), all of the three instances of your library would want to use the same symbol.
There also is a real need interoperability between different libraries, which might not even know about each other. Good examples are transducers, algebraic structures or promises. Would ES6 already be in use, all of these would have agreed on common names in the global symbol registry, instead of relying on strings like these or the then method.
Another good example would be custom hooks defined by your engine, e.g. a Symbol.inspect = Symbol.for("inspect") that you can use to define custom stringification behavior to be used by console.log. Admittedly, that symbol does not necessarily need to be made available through the global symbol registry, it could as well be put on that specific library object (e.g. console.inspect = Symbole("console.inspect")).
And how would I avoid name collisions in that global registry?
Just like you previously did with properties, or global module objects: by using very long, very descriptive names - or by good faith. Also there are some naming conventions.
I invented the most useful feature of Symbol.for() call. If there is using symbols in your code sometimes it is difficult to use conditional breakpoints while debugging. For example, you need to catch if the variable equals the value which is of symbol type and this value binded in the different module. The first difficult way is to use this value as a constant and export it from that module. In this case, the condition of the breakpoint will look:
catchedVariable === exportedSymbolConst
But the easiest way is to temporarily change the code inside the module adding .for to Symbol. Then you can write the condition:
catchedVariable === Symbol.for('string_key')
After the successful debugging you will be changing the code back just removing .for part.

How is concatenating urls in templates in angular less secure than in other locations?

I have an angularjs template which looks similar to this:
<img ng:src="/resources/{{id}}/thumbnail" />
However this results in an $interpolate:noconcat error. In contrast to that this template:
<img ng:src="{{fullUrl}}" />
or even:
<img ng:src="{{id|createThumbnailURL}}" />
(where createThumbnailURL is a simple filter which does the same concatination as above) work totally fine.
The documentation says:
Concatenating expressions makes it hard to reason about whether some
combination of concatenated values are unsafe to use and could easily
lead to XSS.
Well yes, a static URL is always easier to assess than a concatenated one, I see the point there. However it does not sound uncommon to me to have REST-APIs that have URLs that can be constructed by simple concatenation and that concatenation has to be done somehwere. I can do it in the controller or even server-side, but how does that improve anything to move the concatenation elsewhere? And what is the recommended way to deal with the problem?
UPDATE
Here is demo for the error: http://cipher-code.de/tmp/angular3/index.xhtml
Maybe it has to do with the page being XML.
This is called SCE (Strict Contextual Escaping):
Like many "strictness" modes, this is configurable. But as of V 1.2 it is automatically set to true.
More specifically, in contexts Angular considers to be vulnerable (like url's), there is less interpolation allowed (Strictness). Your URL concatenation is being "sanitized".
You are already aware of the reason: XSS attacks. It's also used for the developer's protection: a slightly wrong url could cause data deletes or overwriting.
You're probably confused why full string interpolation ng:src="{{fullUrl}}" is so much safer than string concatenation ng:src="/resources/{{id}}/thumbnail". TBH, I'm not sure there's a serious difference, but these are judgement calls.
You have some alternatives for dealing with this annoyance:
1) Wrap your url construction inside $sce.trustAs()
<img ng:src="sce.trustAs('url', '/resources/{{id}}/thumbnail')" />
2) You can disable SCE across your application, if you choose
angular.module('myApp').config(function($sceProvider) {
$sceProvider.enabled(false);
});
Correction:
You can't call the $sce service from a directive. Only the $scope service is directly available. But you can use a function (or a directive that uses a function).
$scope.createUrl = function (strName) {
var truststring = '/resources/' + strName + '/thumbnail';
return truststring;
}
and your directive call would look like
<img ng:src="{{ createUrl(id) }}" />
In this case, if you wrap your concatenation in a function, you may not even need to de-sanitize it since you won't be breaking SCE rule.
I joined the party a little late, but here are my two cents:
In (very) plain words:
(1)
Angular uses the $sce service to perform "Strict Conceptual Escaping" (SCE). Basically, SCE "requires bindings in certain contexts to result in a value that is marked as safe to use for that context".
It is a protection mechanism provided by Angular to developers to easily protect (some aspects of) your app (this is even more important for apps that bind values based on user's input).
(2)
Some places (i.e. attributes) are considered more vulnerable to certain kinds of attacks (e.g. XSS) and SCE uses more strict rules for them. A few examples are a form's action or a frame's or object's src/ngSrc.
(3)
Based on Angular's current implementation (v1.2.16), an error will be thrown when such a vulnerable attribute is assigned a value that consists of more than 1 "part". A part (accoding to $interpolate service's parsing algorithm is either a part of the expression enclosed in {{ }} or a part of the expression that is outside of {{ }}.
In your case, /resources/{{id}}/thumbnail is parsed into 3 parts:
/resources/, {{id}}, /thumbnail
So, what is the problem with more than 1 part ???
There is nothing inherently more insecure in concatenating in the view vs concatenating in the controller and using a single-part expression.
Quoting from Angular's source (emphasis mine):
// Concatenating expressions makes it hard to reason about whether some combination of
// concatenated values are unsafe to use and could easily lead to XSS. By requiring that a
// single expression be used for iframe[src], object[src], etc., we ensure that the value
// that's used is assigned or constructed by some JS code somewhere that is more testable or
// make it obvious that you bound the value to some user controlled value. This helps reduce
// the load when auditing for XSS issues.
So, it is Angular's way to force a "more secure" practice on you. Constructing the value in the view is less testable and less explicit, so you (or someone else) will have a harder time auditing the app for XSS vulnerabilities (increasing the probability of security issues).
There are a couple of ways (already mentioned in DaveA's answer) to circumvent this.
(I would definitely not entirely disable $sce, though.)

Viable JavaScript Variable Names

This is a two part question: General, and Specific.
For the general: I often find myself wondering what constitutes a viable variable name in JavaScript? I know there are certain 'words' that can not be used as variables in JavaScript; But I have yet to come across either a list of non-viable variable names, or a rule to apply when creating a variable name. I usually err on the side of caution and use obscure names if I am unsure.
It would be nice to know, with certainty, what can be used as a JavaScript variable, and what can not be used.
Any advice?
For the specific: I am wondering if I can use href as a variable name in my JavaScript? Is it viable, or is it reserved?
Afterthought: Perhaps I can extend this question to encompass JavaScript function names as well. What names are viable, and which are reserved? If the two questions are related, I will edit to ask both.
Note: I am not asking which characters can be used in a JavaScript variable; That question is already answered here.
Uhm, actually, you can use any kind of name as a variable name.
Instead of referring to the variable by name, refer to it by array index, since all object properties in JS can be accessed by index*, as well as the fact that global variables are simply properties of the window object.
*a string index can contain literally any kind of character sequence
So the question in turn might be more on the lines of "should I use reserved words as variable names?"
Common sense would say you shouldn't, except when such a name is actually related to the construct and you can't find a suitable replacement.
window['function'] = 2;
window['if'] = 4;
window['var'] = 8;
alert(window['function'] + window['if'] + window['var']);
Warning!
Reserved words are different from native functionality.
Although in many cases you can use names used as reserved keywords as variables, native functionality can actually be overwritten.
For instance Mr Sarris above mentioned Node, (which is a native function not a reserved keyword), you can actually overwrite it by doing window['Node'] = myNewThing;. This has been used in some cases to achieve "wrapper" or "hotfix" functionality, but it is not guaranteed to work in a cross-browser manner (eg; MSIE's console object).
You can find lists of reserved words in JavaScript.
href is certainly fine as a variable name because href is an attribute of an a tag and in no way conflicts with JavaScript naming.
If you are ever in doubt as to whether or not a variable is already in use you can always open the developer tools (F12 in most browsers), go to the console, and type in the name. In this case you'll get:
> href
x ReferenceError: href is not defined
Nothing is using it, so it is yours to use without problem.
Just for kicks if you did enter a reserved word it would look like:
> finally
x SyntaxError: Unexpected token finally
Or if it was a native but already taken word it might look like:
> Node
function Node() { [native code] }
(Node is already defined, and its a native function)
Every programming language has a list of reserved words.
These reserved words consist of the parts that constitute that programming language.
For JavaScript, things like for or function or if are reserved words, since these have special meaning in the language itself. As a rule of thumb you cannot re-use words as identifiers (names) that already have a meaning in that particular language.
The official language specification is a good place to look that up. For JavaScript see the ECMAScript specification, section 7.6.1 (section 7.6. clarifies the other rules that apply to identifier naming).
Your question whether href is okay to use in JS is easily answered by looking there.
rules for variable declaration (on codelifter)
href is ok to use

Categories

Resources