5 ms·
Over-reliance on strings is a pattern that I've seen a lot in the Javascript environment. For example: var arr = [{ value: 'a' }, { value: 'a' }, { value: 'b
by Longwelwind 10y ago
Over-reliance on strings is a pattern that I've seen a lot in the Javascript environment. For example:
var arr = [{ value: 'a' }, { value: 'a' }, { value: 'b' }, { value: 'b' }];
arr.uniqBy('value'); // [{ value: 'a' }, { value: 'b' }]
Wouldn't be better to do something like this ?
var arr = [{ value: 'a' }, { value: 'a' }, { value: 'b' }, { value: 'b' }];
arr.uniqBy(element => element.value); // [{ value: 'a' }, { value: 'b' }]
You have to write a little bit more (I could have used "e" instead of "element", though) but if you do a typo in the name of the property, it can be caught by a linter/compiler, and you don't get the feeling you're relying on Vodoo magic.
Are there any advantages to use a string instead of a "static" way of accessing the property ?
- topaxi 10y agoThe xxBy methods are just for convenience, usually you can provide your own function for each method. Example: Ember.computed.map('myArray', function() { return foo.bar; }) vs. Ember.computed.mapBy('myArray', 'bar') What you are asking for, would need a change to Ember.computed.uniq, allowing it to accept a custom function.
- cnlevy 10y agoSee http://devdocs.io/lodash~4/index#uniqBy http://devdocs.io/lodash~4/index#uniqBy
- orf 10y agoEmberJS uses strings as property paths. You can use 'foo.bar.firstObject.baz' as a unique key the same as any other function that takes a property paths (like a computed property). In Ember you write a lot of these so any small overhead like a lambda is a bit of a waste. Also I don't think ember would work with functions instead of strings, the whole point of the strings is that the unique function is only called when one of the items in the property paths changes, and you can't get that from functions. You can only evaluate them.
- Longwelwind 10y agoThanks, I didn't know that Ember did more than just fetching the value. About time wasted, I feel like in the long run, you gain more time by writing statically analyzable code. If you make a typo in the string, you would have to build/transpile+launch the code in order to see the error. Additionaly, if you ever refactor the name of the property, the linter will directly tell you that "value" in the lambda must be changed.
- orf 10y agoI agree and one of the downsides is exactly this. I've felt this pain before :( But there is no way around it - property keys are strings because they can be many layers deep (`foo.bar.test.abc`), and if any of those are undefined then the result is undefined. Also any of those properties (`foo`, `bar`, `test` or `abc`) could be themselves computed properties that depend on others. You also get features like `@each`, used for arrays like `foo.@each.bar`. Perhaps a good middleground would be to do something like C#'s LINQ stuff, where the lambdas are analysed and the values extracted.
- pandler 10y ago> if you do a typo in the name of the property, it can be caught by a linter/compiler There isn't really great linter/compiler support for ember anyways, mainly because of how you're forced to use getters and setters. In ember, your example would look like var arr = [{ value: 'a' }, { value: 'a' }, { value: 'b' }, { value: 'b' }]; arr.uniqBy(element => element.get('value')); // [{ value: 'a' }, { value: 'b' }] The `element.get('value')` syntax makes it hard to do static analysis on your code. It's a bit of a pain point, but that design decision wasn't arbitrary and there are lengthy explanations for why they designed the framework like that. > Are there any advantages to use a string instead of a "static" way of accessing the property ? It's just shorthand for (what I imagine is) the most common use-case. Keep in mind that `uniqBy` is a property macro, which provide simplified apis for very specific use-cases. You always have the ability to write more complex, custom computed properties.
- akst 10y agoWhile I believe it would be nice to have a lambda version of this as it's a more general abstraction (and I believe there's something along those lines in ember), Ember makes a big emphasis on convention over configuration and this isn't limited to the build system but also it's runtime apis as well. It's pretty common in ember to look up a property by string to set or get using the methods `get` and `set` on an ember object (ember has it's own object model[1]), and these property keys/strings can also express nested properties by spacing dots between nested property names. Like `user.get('organisation.name')` to get an user's organisation and the name of the organisation, this handles the situation when organisation is null, by returning null. So it's similar to `user.organisation?.name` in swift. So for consistency sake and predictability sake ember also uses a string for this method. If we look at the implementation[2] you can see it use's a method called `guidFor`, it basically handles the whole null checking stuff, which in a lambda version would look something like var arr = [{ value: 'a' }, { value: 'a' }, { value: 'b' }, { value: 'b' }]; arr.uniqBy(element => (element != null) ? element.value : null); `guidFor`[3] also works for nested properties as well, so if you were looking for a property on `value` it would starts to get messy. [1]: https://guides.emberjs.com/v2.1.0/object-model/ https://guides.emberjs.com/v2.1.0/object-model/ [2]: https://github.com/emberjs/ember.js/blob/45c92fb2c8931b4ca41313b52c2ea5e4a4444a8e/packages/ember-runtime/lib/mixins/enumerable.js#L1095 https://github.com/emberjs/ember.js/blob/45c92fb2c8931b4ca41... [3]: https://github.com/emberjs/ember.js/blob/45c92fb2c8931b4ca41313b52c2ea5e4a4444a8e/packages/ember-metal/lib/utils.js#L181 https://github.com/emberjs/ember.js/blob/45c92fb2c8931b4ca41...