Skip to content

Commit

Permalink
deprecate {{with}}
Browse files Browse the repository at this point in the history
  • Loading branch information
GavinJoyce committed Feb 15, 2019
1 parent 455991d commit 3dff63a
Showing 1 changed file with 148 additions and 0 deletions.
148 changes: 148 additions & 0 deletions text/0000-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
- Start Date: 2019-02-13
- Relevant Teams: Ember.js, Learning
- RFC PR: https://github.com/emberjs/rfcs/pull/445
- Tracking: (leave this empty)

# Deprecate `{{with}}`

## Summary

The `{{with}}` helper has always had slightly confusing conditional semantics, this was one of the motivators for [introducing](https://github.com/emberjs/rfcs/blob/master/text/0286-block-let-template-helper.md) the easier to understand `{{let}}` helper. Now that `{{let}}` exists, the remaining use case for using `{{with}}` is for its unique conditional semantics. These conditional semantics can be cleanly represented with a combination of `{{let}}` and `{{if}}` statements so we should deprecate `{{with}}`.

## Motivation

The difference between `{{let}}` and `{{with}}` is with how they handle conditional arguments. The `{{let}}` helper's block content is always rendered, regardless of its parameters. In contrast, `{{with}}` only renders its main block when the first position parameter is truthy. For example:

```hbs
{{#with "Alex" as |value|}}
{{value}} is truthy
{{else}}
The first positional param was falsy
{{/with}}
```

Will render "[Alex] is truthy".

```hbs
{{#with false as |value|}}
{{value}} is truthy
{{else}}
The first positional param was falsy
{{/with}}
```

Will render "The first positional param was falsy".

The conditional arguments behavior of `{{with}}` can easily be replicated using a combination of `{{let}}` and `{{if}}` in a way that's easily readable:

```hbs
{{#let "Alex" as |value|}}
{{#if value}}
{{value}} is truthy
{{else}}
The first positional param was falsy
{{/if}}
{{/let}}
```

## Detailed design

We'll create an AST transform in [`packages/ember-template-compiler`](https://github.com/emberjs/ember.js/tree/master/packages/ember-template-compiler) which will emit a deprecation warning for all uses of `{{with}}`. The deprecation warning will be:

```
Using `{{with}}` is deprecated, please use `{{let}}` instead.
```

This message will link to the following deprecation details which aim to give clear guidance on how to migrate to using `{{let}}`, `{{if}}` and `{{else}}` in different combinations:

----

The use of `{{with}}` has been deprecated, you should replace it with either `{{let}}` or a combination of `{{let}}`, `{{if}}` and `{{else}}`:

**If you always want the block to render, replace `{{with}}` with `{{let}}` directly:**

Before:

```hbs
{{#with (hash name="Ben" age=4) as |person|}}
Hi {{person.name}}, you are {{person.age}} years old.
{{/with}}
```

After:

```hbs
{{#let (hash name="Ben" age=4) as |person|}}
Hi {{person.name}}, you are {{person.age}} years old.
{{/let}}
```

**If you want to render a block conditionally, use a combination of `{{let}}` and `{{if}}`:**

Before:

```hbs
{{#with user.posts as |blogPosts|}}
There are {{blogPosts.length}} blog posts
{{/with}}
```

After:

```hbs
{{#let user.posts as |blogPosts|}}
{{#if blogPosts}}
There are {{blogPosts.length}} blog posts
{{/if}}
{{/let}}
```

**If you want to render a block conditionally, and otherwise render an alternative block, use a combination of `{{let}}`, `{{if}}` and `{{else}}`:**

Before:

```hbs
{{#with user.posts as |blogPosts|}}
There are {{blogPosts.length}} blog posts
{{else}}
There are no blog posts
{{/with}}
```

After:

```hbs
{{#let user.posts as |blogPosts|}}
{{#if blogPosts}}
There are {{blogPosts.length}} blog posts
{{else}}
There are no blog posts
{{/if}}
{{/let}}
```

---

For people on older versions of Ember that support `{{let}}`, we'll create an `ember-template-lint` rule that they can use to prevent the use of `{{with}}`.

## How we teach this

We'll mentiton the deprecation in an Ember point release blog post.

As mentioned above, the deprecation message will contain a link to clear guidelines on how to migrate to using `{{let}}`.

## Drawbacks

This adds a little churn to Ember's API.

## Alternatives

We could leave `{{with}}` as is. I don't believe that this is a good option as the name `{{with}}` is confusing.

We could deprecate `{{with}}` and introduce `{{if-let}}` in Ember core. This RFC originally made that exact proposal, I was strongly persuaded of the [lack of need for `{{if-let}}` by @tcjr](https://github.com/emberjs/rfcs/pull/445#issuecomment-463594185).

We could deprecate `{{with}}` and introduce `{{if-let}}` in an addon instead of Ember core.

## Unresolved questions

(none)

0 comments on commit 3dff63a

Please sign in to comment.