diff --git a/src/generators/dom/visitors/Element/Binding.ts b/src/generators/dom/visitors/Element/Binding.ts
index edc3767c0e..6be11e86a5 100644
--- a/src/generators/dom/visitors/Element/Binding.ts
+++ b/src/generators/dom/visitors/Element/Binding.ts
@@ -61,7 +61,7 @@ export default function visitBinding(
type
);
- let setter = getSetter(block, name, snippet, state.parentNode, attribute, dependencies, value);
+ let setter = getSetter(generator, block, name, snippet, state.parentNode, attribute, dependencies, value);
let updateElement = `${state.parentNode}.${attribute.name} = ${snippet};`;
const needsLock = !isReadOnly && node.name !== 'input' || !/radio|checkbox|range|color/.test(type); // TODO others?
@@ -290,6 +290,7 @@ function getBindingGroup(generator: DomGenerator, value: Node) {
}
function getSetter(
+ generator: DomGenerator,
block: Block,
name: string,
snippet: string,
@@ -319,6 +320,15 @@ function getSetter(
}
if (attribute.value.type === 'MemberExpression') {
+ // This is a little confusing, and should probably be tidied up
+ // at some point. It addresses a tricky bug (#893), wherein
+ // Svelte tries to `set()` a computed property, which throws an
+ // error in dev mode. a) it's possible that we should be
+ // replacing computations with *their* dependencies, and b)
+ // we should probably populate `generator.readonly` sooner so
+ // that we don't have to do the `.some()` here
+ dependencies = dependencies.filter(prop => !generator.computations.some(computation => computation.key === prop));
+
return deindent`
var state = #component.get();
${snippet} = ${value};
diff --git a/test/runtime/samples/binding-indirect-computed/_config.js b/test/runtime/samples/binding-indirect-computed/_config.js
new file mode 100644
index 0000000000..f7ac841f21
--- /dev/null
+++ b/test/runtime/samples/binding-indirect-computed/_config.js
@@ -0,0 +1,32 @@
+export default {
+ dev: true,
+
+ html: `
+
+ `,
+
+ test(assert, component, target, window) {
+ const select = target.querySelector('select');
+ const options = target.querySelectorAll('option');
+
+ const change = new window.Event('change');
+
+ options[1].selected = true;
+ select.dispatchEvent(change);
+
+ assert.equal(component.get('selected').letter, 'B');
+ assert.htmlEqual(target.innerHTML, `
+
+
+ B
+ `);
+ }
+};
\ No newline at end of file
diff --git a/test/runtime/samples/binding-indirect-computed/main.html b/test/runtime/samples/binding-indirect-computed/main.html
new file mode 100644
index 0000000000..88e638bf30
--- /dev/null
+++ b/test/runtime/samples/binding-indirect-computed/main.html
@@ -0,0 +1,27 @@
+
+
+{{selected.letter}}
+
+
\ No newline at end of file