Repository: sveltejs/svelte (JavaScript)
Date: 2018-07-08 14:57:59+00:00
Task type: Bug Fix

Issue:
if_block_creators[current_block_type_index] is not a function
I was trying to create component with several if-else statements, that depends on component data variable. 

First statement block should add one of nested components, second statement block should add some button tags.

I got an error **if_block_creators[current_block_type_index] is not a function**

https://svelte.technology/repl?version=2.9.1&gist=6e02554521c9ea732c3b7e8a883ef664




Issue discussion:
(Things are a bit more confusing in the REPL at the moment than the should be because of [this issue](https://github.com/sveltejs/svelte.technology/issues/327). For now, it's best to look at this by downloading the .zip and running it locally.)

The issue here seems to be that the two `select_block_type` functions are getting the same name - one of them isn't a `select_block_type_1`. I'm not sure why this is the case. This causes this particular exception here because the second one (for the second if with the `<button>`s) returns the block itself, while the first one (for the if with the `<NestedComponent>`s) returns a 0 or a 1 because of the separate handling for (potential) outros in sub-components. The second `select_block_type` overwrites the first, and we end up trying to use the block object as an index into an array.

Solution patch:
diff --git a/src/compile/nodes/IfBlock.ts b/src/compile/nodes/IfBlock.ts
--- a/src/compile/nodes/IfBlock.ts
+++ b/src/compile/nodes/IfBlock.ts
@@ -250,7 +250,7 @@ export default class IfBlock extends Node {
 		dynamic,
 		{ name, anchor, hasElse }
 	) {
-		const select_block_type = block.getUniqueName(`select_block_type`);
+		const select_block_type = this.compiler.getUniqueName(`select_block_type`);
 		const current_block_type_index = block.getUniqueName(`current_block_type_index`);
 		const previous_block_index = block.getUniqueName(`previous_block_index`);
 		const if_block_creators = block.getUniqueName(`if_block_creators`);


Test patch:
diff --git a/test/runtime/samples/if-block-outro-unique-select-block-type/Component.html b/test/runtime/samples/if-block-outro-unique-select-block-type/Component.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/if-block-outro-unique-select-block-type/Component.html
@@ -0,0 +1 @@
+<div></div>
diff --git a/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js b/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/if-block-outro-unique-select-block-type/_config.js
@@ -0,0 +1,7 @@
+export default {
+	nestedTransitions: true,
+	html: `
+		<div></div>
+		<div></div>
+	`,
+};
diff --git a/test/runtime/samples/if-block-outro-unique-select-block-type/main.html b/test/runtime/samples/if-block-outro-unique-select-block-type/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/if-block-outro-unique-select-block-type/main.html
@@ -0,0 +1,20 @@
+{#if foo}
+	<Component/>
+{:else}
+	<Component/>
+{/if}
+
+{#if foo}
+	<div></div>
+{:else}
+	<div></div>
+{/if}
+
+<script>
+	export default {
+		components: {
+			Component: './Component.html',
+		},
+		data: () => ({ foo: true }),
+	}
+</script>