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

Destructuring let attribute in <For> component #3059

Closed
bicarlsen opened this issue Oct 2, 2024 · 2 comments · Fixed by #3383
Closed

Destructuring let attribute in <For> component #3059

bicarlsen opened this issue Oct 2, 2024 · 2 comments · Fixed by #3383
Labels
documentation Improvements or additions to documentation

Comments

@bicarlsen
Copy link
Contributor

Is your feature request related to a problem? Please describe.
When iterating over a structured type (i.e. a tuple or struct) in a <For> component, it would be convenient if we could destructure it in the let attribute. To do this at the moment requires additional boilerplate.
e.g.

struct Item {
  pub name: String,
  pub value: String,
}

#[component]
fn List(list: Vec<Item>) -> impl IntoView {
  view! {
    <For
      each=move || list
      key=|(name, _)| name.clone()
      let:item
    >
      {move || { // Boilerplate to destructure
        let Item { name, value } = &item;
        view! {
          <div>{name} ": " {description}</div>
        }
      }}
    </For>
  }
}
type Point = (i32, i32);

#[component]
fn Points(points: Vec<Point>) -> impl IntoView {
  view! {
    <For
      each=move || points
      key=|point| point
      let:point
    >
      {move || { // Boilerplate to destructure
        let (x, y) = point;
        view! {
          <div>{x} ", " {y}</div>
        }
      }}
    </For>
  }
}

Describe the solution you'd like
It would be nice to allow destructuring in the let attribute to remove this additional layer of code.

#[component]
fn List(list: Vec<Item>) -> impl IntoView {
  view! {
    <For
      each=move || list
      key=|(name, _)| name.clone()
      let:Item { name, value }  // Destructure in `let`
    >
      <div>{name} ": " {description}</div>
    </For>
  }
}
#[component]
fn Points(points: Vec<Point>) -> impl IntoView {
  view! {
    <For
      each=move || points
      key=|point| point
      let:(x, y)  // Destructure in `let`
    >
      <div>{x} ", " {y}</div>
    </For>
  }
}
@bicarlsen bicarlsen changed the title Destructure in `<For let: /> Destructuring let attribute in <For> component Oct 2, 2024
@gbj gbj added the documentation Improvements or additions to documentation label Oct 2, 2024
@gbj
Copy link
Collaborator

gbj commented Oct 2, 2024

There's a syntax for this implemented by #2655. The below compiles. Note the let(/* pattern */) syntax.

#[derive(Clone)]
struct Item {
    pub name: String,
    pub value: String,
}

#[component]
fn List(list: ReadSignal<Vec<Item>>) -> impl IntoView {
    view! {
      <For
        each=move || list.get()
        key=|Item { name, .. }| name.clone()
        let(Item { name, value })
      >
        <div>{name} ": " {value}</div>
      </For>
    }
}

Tagging this as "documentation" because I'm sure this is not actually documented anywhere.

@bicarlsen
Copy link
Contributor Author

Awesome!

@gbj gbj closed this as completed in #3383 Dec 20, 2024
gbj pushed a commit that referenced this issue Dec 20, 2024
* docs: showcase let syntax in for_loop

* fix: doctests on for_loop

---------

Co-authored-by: Oliver Nordh <oliver.nordh@proton.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants