Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{{#each things as thing by thing}} #703

Closed
Rich-Harris opened this issue Jul 8, 2017 · 13 comments · Fixed by #1381
Closed

{{#each things as thing by thing}} #703

Rich-Harris opened this issue Jul 8, 2017 · 13 comments · Fixed by #1381

Comments

@Rich-Harris
Copy link
Member

As mentioned in #700, it's sometimes useful to be able to use a list item as the basis for keyed updates, rather than a property of each list item.

That could be done a few different ways, e.g.:

{{#each things as thing @}}
{{#each things as thing @this}}
{{#each things as thing by thing}}

One potentially nice feature of the last option, apart from the fact that it doesn't have off-putting special characters, is that it could be more flexible — as well as by thing or by thing.id it could potentially be any expression:

{{#each things as thing by getId(thing)}}

Haven't looked into whether that's feasible. Just wondering about whether it would be desirable if so. Thoughts?

@antony
Copy link
Member

antony commented Jul 12, 2017

I actually really hate this in AngularJS. I can never get it right, and the documentation is very unclear.

The only support I'd want to see is the ability to iterate Objects by key, which could be done in a simple, javascripty way:

{{ #each things as key, value }}

@TehShrike
Copy link
Member

It seems #704 canonizes the @property syntax, so I'd favor sticking close to that, so I don't have to remember the difference between @ and by.

Since this is a valid property name, {{#each things as thing @}} seems best to me?

@aubergene
Copy link

I like the idea of this as I could imagine reusing a key function that gets passed around to various places

@tivac
Copy link
Contributor

tivac commented Jan 23, 2018

I've got a few thoughts about each of the current proposals:

{{#each things as thing @}}

Looks like you forgot to type a value after the @

{{#each things as thing @this}}

this has its own baggage and seems likely to cause confusion.

{{#each things as thing by thing}}

Keyed updates are already using the @<key> syntax, so this seems like a non-starter.

For this particular use-case I'd expect something like

{{#each things as thing @thing}}

Which clearly illustrates the intent of using thing itself as the key. It requires some repetition but the clarity is worth it over the terseness of just using @.

@ChrisTalman
Copy link

I'd like to add that, if there's any doubt as to the desirability of this feature, it'd be really useful for generic reusable components which act upon arrays of varying objects. For instance, user code might provide an array of objects of any kind to a reusable component, and could specify the unique key, or a method to generate the unique key, for each object, for the reusable component to use.

On the matter of syntax, I feel that by with an expression is most appropriate. To start with, it's most JavaScript-like, which seems appropriate given we work in the context of JavaScript and Svelte has mostly been built with this in mind. Second, it follows logically from the rest of the {{each}} block, which already uses another keyword, as. And finally, it carries more semantic meaning, by virtue of it being a word. Even if @ is understood as 'at', it makes more sense to say that an {{each}} block is keyed by a key, not at a key. In contrast, the current @ syntax lacks these advantages, which make it seem out of place. The strength of by, as an expression, can be demonstrated by a number of examples.

{{#each things as thing by 'key'}}
{{#each things as thing by keyProperty}}
{{#each things as thing by options.key}}
{{#each things as thing by thing.getKey()}}
{{#each things as thing by getKey(thing)}}

I don't think the existence of the current @ syntax should be an impediment to shifting to by from this point onwards. It should be possible to continue to allow @ syntax in its current form for the foreseeable future for backwards compatibility, and potentially eventually deprecate it. It also doesn't seem like the @ syntax easily lends itself to supporting an expression. The text to the right of the @ is currently treated as the key itself, and so an expression would need to be denoted by further special symbols, like @<expressionReturningKey>.

I can't comment on the feasibility, but I hope it's not problematic.

So, I think there's pretty good reason, both for this feature as a concept, and for its implementation with the by expression syntax in particular.

@tomcon
Copy link

tomcon commented Mar 30, 2018

Something related here but not mentioned is that we will need to have keyed each block support using an array index too.

For larger lists I always get the value from the server the fastest way possible as a json array of array of values only (rather than an array of objects with the keys being repeated for every single row).

{{#each rs as o @o[1]}} 
or (my vote in this situation)
{{#each rs as o @1}} 

@mrkishi
Copy link
Member

mrkishi commented Mar 30, 2018

I assume that'd be supported by the by construct:

{{#each things as thing by thing[1]}}

This seems like the most flexible approach-- and I like the fact that it doesn't use sigils.

@tivac
Copy link
Contributor

tivac commented Apr 26, 2018

Seems like this was closed by #1318?

https://svelte.technology/guide#keyed-each-blocks

{#each things as thing (thing.key)}

@Conduitry
Copy link
Member

The syntax has changed, but what's actually permitted as a keyed index has not. IMO this should not be closed until arbitrary expressions are allowed as keys.

@Rich-Harris
Copy link
Member Author

Not quite — the syntax is there, but it doesn't currently support any form other than (x.y)

@Rich-Harris
Copy link
Member Author

dammit @Conduitry. yes, exactly that

@tivac
Copy link
Contributor

tivac commented Apr 26, 2018

So given that the syntax should be {#each things as thing (thing)} and now it needs to be implemented?

@Rich-Harris
Copy link
Member Author

This is implemented in 2.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants