Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$interpolate : add a way to hook string representation #7317

Closed
jpolo opened this issue Apr 30, 2014 · 4 comments
Closed

$interpolate : add a way to hook string representation #7317

jpolo opened this issue Apr 30, 2014 · 4 comments

Comments

@jpolo
Copy link

jpolo commented Apr 30, 2014

$interpolate has only two behavior for stringify : IF string THEN output without change OR perform json conversion.
It would be helpful to add a detection for hookable toString behavior for objects that are always represented by string or number (= where json representation has no value at all).

Use case: when using custom Int64, URI, ..., objects, everybody would expect that {{myUri}} would display a string representation instead of a json representation or a quoted string.

Idea of implementations :

  • detect that valueOf or toString is overriden ?
  • add a callback in $interpolate module ?
  • apply toJson only for plain objects (i.e. where Object.getPrototypeOf(o) === Object.prototype) ?
@btford
Copy link
Contributor

btford commented May 1, 2014

I think this is better solved by a filter.

@btford btford added this to the Ice Box milestone May 1, 2014
@jpolo
Copy link
Author

jpolo commented May 2, 2014

If we consider $interpolate result functionnally then foo {{myVar}} bar is equivalent to return "foo " + myVar + " bar" and foo {{myVar|filter}} bar is equivalent to return "foo " + filter(myVar) + " bar" .
Nevertheless, I understand why a toJson conversion was applied in some cases : when myVar = {} it would display always [object Object]. This has strictly no interest for developer.

Knowing that there is a filter |json when a json representation is wanted (= only for debug dump), it would be verbose to create a filter |string that would just be return String(myVar) and that we would have to have to call in every template expression.

@rodyhaddad
Copy link
Contributor

@jpolo I believe @btford is proposing you create a filter for each type of object.

So using {{ myInts | ints }} or {{ myUrl | url }} is a lot better than having $interpolate do its own sniffing, adding more magic to maintain, with potential corner cases that might cause debugging problems to others.

It's better to be explicit than implicit here.

@jpolo
Copy link
Author

jpolo commented May 7, 2014

Creating and using the filter is always the solution because it's explicit, I cannot deny that. This issue is more about the unexpected behavior that I felt when using $interpolate with no filter : I had to see the code to understand why it worked like that.
Why ? It might be developer's culture: in most languages (Python etc) string conversion is the default filter. (ex: https://docs.python.org/2/library/string.html#formatspec)
In the current implementation, it's a mix of "string unchanged, jsonify the rest" that can be confusing.

Maybe sniffing is not the best choice, you're right. But a simple String conversion as default behavior is preferrable. As you said, better be explicit and use |json when wanting json representation.

danielkrainas added a commit to danielkrainas/angular.js that referenced this issue Jul 26, 2014
BREAKING CHANGE: use custom toString implementation when present on object value types.
Behavior is consistent with other implementations and can be seen as an implicit behavior.

Closes angular#7317
danielkrainas added a commit to danielkrainas/angular.js that referenced this issue Jul 26, 2014
BREAKING CHANGE: use custom toString implementation when present on object value types.
Behavior is consistent with other implementations.

Closes angular#7317
danielkrainas added a commit to danielkrainas/angular.js that referenced this issue Jul 28, 2014
BREAKING CHANGE: use custom toString implementation when present on object value types.
Behavior is consistent with implementations found in other languages such as Ruby, Python, and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

Closes angular#7317
@btford btford removed the gh: issue label Aug 20, 2014
Narretz pushed a commit to Narretz/angular.js that referenced this issue Jun 8, 2016
This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

Fixes angular#7317
Closes angular#8350

BREAKING CHANGE:

When converting values to strings, interpolation now uses a custom toString() function on objects
that are not numbers, dates or arrays (custom means that the `toString()` function is not the same as
`Object.prototype.toString()`). Otherwise, interpolation uses JSON.stringify() as usual.

Should you have a custom toString() function but still want the output of JSON.stringify(), migrate
as shown in the following examples:

Before:

```html
<span>{{myObject}}</span>
```

After - use the `json` filter to stringify the object:

```html
<span>{{myObject | json}}</span>
```
Narretz pushed a commit to Narretz/angular.js that referenced this issue Jun 8, 2016
This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

Fixes angular#7317
Closes angular#8350

BREAKING CHANGE:

When converting values to strings, interpolation now uses a custom toString() function on objects
that are not numbers or arrays (custom means that the `toString()` function is not the same as
`Object.prototype.toString()`). Otherwise, interpolation uses JSON.stringify() as usual.

Should you have a custom toString() function but still want the output of JSON.stringify(),
migrate as shown in the following examples:

Before:

```html
<span>{{myObject}}</span>
```

After - use the `json` filter to stringify the object:

```html
<span>{{myObject | json}}</span>
```

fixup
Narretz added a commit to Narretz/angular.js that referenced this issue Jun 22, 2016
Except on Numbers, Dates and Arrays.

Thanks to @danielkrainas for the initial implementation of this feature.

This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

The commit also exposes a private $$stringify method on the angular global, so that ngMessageFormat
can use the same logic without duplicating it.

Fixes angular#7317
Closes angular#8350

BREAKING CHANGE:

When converting values to strings, interpolation now uses a custom toString() function on objects
that are not Number, Array or Date (custom means that the `toString()` function is not the same as
`Object.prototype.toString()`). Otherwise, interpolation uses JSON.stringify() as usual.

Should you have a custom toString() function but still want the output of JSON.stringify(),
migrate as shown in the following examples:

Before:

```html
<span>{{myObject}}</span>
```

After - use the `json` filter to stringify the object:

```html
<span>{{myObject | json}}</span>
```
Narretz added a commit to Narretz/angular.js that referenced this issue Jun 22, 2016
Except on Numbers, Dates and Arrays.

Thanks to @danielkrainas for the initial implementation of this feature.

This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

The commit also exposes a private $$stringify method on the angular global, so that ngMessageFormat
can use the same logic without duplicating it.

Fixes angular#7317
Closes angular#8350

BREAKING CHANGE:

When converting values to strings, interpolation now uses a custom toString() function on objects
that are not Number, Array or Date (custom means that the `toString()` function is not the same as
`Object.prototype.toString()`). Otherwise, interpolation uses JSON.stringify() as usual.

Should you have a custom toString() function but still want the output of JSON.stringify(),
migrate as shown in the following examples:

Before:

```html
<span>{{myObject}}</span>
```

After - use the `json` filter to stringify the object:

```html
<span>{{myObject | json}}</span>
```
Narretz added a commit to Narretz/angular.js that referenced this issue Jun 24, 2016
Except on Numbers, Dates and Arrays.

Thanks to @danielkrainas for the initial implementation of this feature.

This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

The commit also exposes a private $$stringify method on the angular global, so that ngMessageFormat
can use the same logic without duplicating it.

Fixes angular#7317
Closes angular#8350

BREAKING CHANGE:

When converting values to strings, interpolation now uses a custom toString() function on objects
that are not Number, Array or Date (custom means that the `toString()` function is not the same as
`Object.prototype.toString()`). Otherwise, interpolation uses JSON.stringify() as usual.

Should you have a custom toString() function but still want the output of JSON.stringify(),
migrate as shown in the following examples:

Before:

```html
<span>{{myObject}}</span>
```

After - use the `json` filter to stringify the object:

```html
<span>{{myObject | json}}</span>
```
Narretz added a commit to Narretz/angular.js that referenced this issue Jun 24, 2016
Except on Numbers, Dates and Arrays.

Thanks to @danielkrainas for the initial implementation of this feature.

This behavior is consistent with implementations found in other languages such as Ruby, Python,
and CoffeeScript.
http://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics
https://docs.python.org/2/library/stdtypes.html#string-formatting-operations
http://coffeescriptcookbook.com/chapters/strings/interpolation

The commit also exposes a private $$stringify method on the angular global, so that ngMessageFormat
can use the same logic without duplicating it.

Fixes angular#7317
Closes angular#8350
Fixes angular#11406

BREAKING CHANGE:

When converting values to strings, interpolation now uses a custom toString() function on objects
that are not Number, Array or Date (custom means that the `toString` function is not the same as
`Object.prototype.toString`). Otherwise, interpolation uses JSON.stringify() as usual.

Should you have a custom toString() function but still want the output of JSON.stringify(),
migrate as shown in the following examples:

Before:

```html
<span>{{myObject}}</span>
```

After - use the `json` filter to stringify the object:

```html
<span>{{myObject | json}}</span>
```
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants