sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.39k stars 4.1k forks source link

undefined/null values shouldn't be cast to String #659

Closed vp2177 closed 7 years ago

vp2177 commented 7 years ago

In my opinion it would be more useful if null/undefined/false would result in no text node at all in <element>{{}}</element>, and would remove the attribute it's set to in case of <element attribute='{{}}'>

Please take a look at this demostration of "questionable" String casts: https://svelte.technology/repl?version=1.22.5&gist=a63a1bbf1dec86521bbd238699e7ffdf

Rich-Harris commented 7 years ago

Thanks for opening an issue. We discussed a related case in https://github.com/sveltejs/svelte/issues/249#issuecomment-273283992, and I think the same situation applies here — there's really no reason why undefined and null should be turned into the empty string, since it's really just masking an error. Explicitly initialising your data is the recommended approach (or, if you can't for whatever reason, then doing {{obj.missing || ''}} instead of just {{obj.missing}}).

In any case, it would result in a lot of wasted code being generated. At the moment, the code that gets generated for e.g. {{obj.missing}} is this:

var text_5 = createText(text_5_value = state.obj.missing);

// later, when updating
if (text_5_value !== (text_5_value = state.obj.missing)) {
  text_5.data = text_5_value;
}

Changing it to this, which is what would be necessary...

var text_5 = createText((text_5_value = state.obj.missing) == null ? '' : text_5_value);

// later, when updating
if (text_5_value !== (text_5_value = state.obj.missing)) {
  text_5.data = text_5_value == null ? '' : text_5_value;
}

...isn't desirable, even if the resulting behaviour was. So I'll close this as wontfix.

ricardobeat commented 6 years ago

Is it possible to override the default __escape method?

This would allow us to implement this behavior at runtime (without resorting to a Proxy object). I'm evaluating using Svelte for a project where dropping 'undefined' in front of users is not really the desired outcome in production, regardless of what failed. Requiring everyone to write a manual fallback for every interpolated value in the codebase is also not feasible.