diff --git a/conda/js/src/components/experiment/ExperimentEditor.jsx b/conda/js/src/components/experiment/ExperimentEditor.jsx
index d6c0a1d970e7fb159b0c0646a7b61e46c873bac0..f53a51baf91a774d718e35463bc5b9a099f36a7e 100644
--- a/conda/js/src/components/experiment/ExperimentEditor.jsx
+++ b/conda/js/src/components/experiment/ExperimentEditor.jsx
@@ -4,7 +4,7 @@ import {
 	Container,
 	Row,
 	Col,
-	Button,
+	Button, ButtonGroup,
 	Form,
 	FormGroup,
 	Label,
@@ -765,6 +765,17 @@ export class ExperimentEditor extends React.Component<Props, State> {
 		const queue = block.queue || this.props.data.contents.globals.queue;
 		const envDisabled = !block.hasOwnProperty('environment');
 
+		const getClearedGlobals = () => {
+			const globals = copyObj(this.props.data.contents.globals);
+			// if the old algorithm had parameters and no other block is using that alg,
+			// delete the global param defaults for the old alg
+			if(globals.hasOwnProperty(block.algorithm) &&
+				[...this.props.toolchain.contents.analyzers, ...this.props.toolchain.contents.blocks]
+				.filter(b => b.algorithm === block.algorithm).length <= 1)
+				delete globals[block.algorithm];
+			return globals;
+		};
+
 		return (
 			<FormGroup key={key} className={`block${ key } block_${ blockName }`}>
 				<h4>
@@ -874,7 +885,8 @@ export class ExperimentEditor extends React.Component<Props, State> {
 										thisBlock.outputs = levMapStrings(Object.keys(outputs), tcBlock.outputs);
 
 									// setup the parameters (erase & create stuff)
-									const globals = copyObj(this.props.data.contents.globals);
+									const globals = getClearedGlobals();
+
 									// if the new alg has parameters, gen the global defaults for the params
 									if(alg.contents.parameters && Object.keys(alg.contents.parameters).length > 0)
 										globals[alg.name] = {
@@ -884,13 +896,6 @@ export class ExperimentEditor extends React.Component<Props, State> {
 											...this.props.data.contents.globals[alg.name],
 										};
 
-									// if the old algorithm had parameters and no other block is using that alg,
-									// delete the global param defaults for the old alg
-									if(globals.hasOwnProperty(block.algorithm) &&
-										[...this.props.toolchain.contents.analyzers, ...this.props.toolchain.contents.blocks]
-										.filter(b => b.algorithm === block.algorithm).length <= 1)
-										delete globals[block.algorithm];
-
 									updateBlock(thisBlock, globals);
 									this.setLockMap(blockName, true);
 								}}
@@ -905,44 +910,66 @@ export class ExperimentEditor extends React.Component<Props, State> {
 								}
 							</Input>
 						</Col>
-						{ !isAnalyzer &&
-								<Col sm='auto'>
-									<Button
-										color='primary'
-										disabled={block.algorithm === ''}
-										title={`Copies the algorithm & IO mappings to all unconfigured blocks with the same inputs & outputs`}
-										onClick={() => {
-											// copy the algorithm and input/output mappings to blocks
-											// that are the same except for the block name and dont have an algorithm assigned already
-											const targetBlocks = this.props.toolchain.contents.blocks
-											// not the block being copied from
-											.filter(b => b.name !== blockName)
-											// same IO
-											.filter(b => JSON.stringify(b.inputs) === JSON.stringify(tcBlock.inputs))
-											.filter(b => JSON.stringify(b.outputs) === JSON.stringify(tcBlock.outputs))
-											.map(b => b.name)
-											;
-											//console.log(targetBlocks);
-
-											// because the target blocks have the exact same inputs/outputs as the current block
-											// we dont need to re-compute the block object that we will copy!
-											// instead, just reuse the current block object and assign it to all
-											// the target blocks.
-											// also, because all these blocks are the same algorithm as the current block
-											// we dont need to mess with the globals.
-
-											const newBlocks = copyObj(this.props.data.contents.blocks);
-											targetBlocks.forEach(bName => { newBlocks[bName] = copyObj(block); });
-											this.setContents({
-												...this.props.data.contents,
-												blocks: newBlocks,
-											});
-										}}
-									>
-										Copy to similar blocks
-									</Button>
-								</Col>
-						}
+						<Col sm='auto'>
+							{ !isAnalyzer &&
+									<React.Fragment>
+										<Button
+											color='primary'
+											disabled={block.algorithm === ''}
+											title={`Copies the algorithm & IO mappings to all unconfigured blocks with the same inputs & outputs`}
+											onClick={() => {
+												// copy the algorithm and input/output mappings to blocks
+												// that are the same except for the block name and dont have an algorithm assigned already
+												const targetBlocks = this.props.toolchain.contents.blocks
+												// not the block being copied from
+												.filter(b => b.name !== blockName)
+												// same IO
+												.filter(b => JSON.stringify(b.inputs) === JSON.stringify(tcBlock.inputs))
+												.filter(b => JSON.stringify(b.outputs) === JSON.stringify(tcBlock.outputs))
+												.map(b => b.name)
+												;
+												//console.log(targetBlocks);
+
+												// because the target blocks have the exact same inputs/outputs as the current block
+												// we dont need to re-compute the block object that we will copy!
+												// instead, just reuse the current block object and assign it to all
+												// the target blocks.
+												// also, because all these blocks are the same algorithm as the current block
+												// we dont need to mess with the globals.
+
+												const newBlocks = copyObj(this.props.data.contents.blocks);
+												targetBlocks.forEach(bName => { newBlocks[bName] = copyObj(block); });
+												this.setContents({
+													...this.props.data.contents,
+													blocks: newBlocks,
+												});
+											}}
+										>
+											Copy to similar blocks
+										</Button>
+										{' '}
+									</React.Fragment>
+							}
+							<Button
+								color='secondary'
+								title={`Clears the block data, resetting the selected block.`}
+								onClick={() => {
+									const newBlock = copyObj(block);
+									const newGlobals = getClearedGlobals();
+									newBlock.algorithm = '';
+									if(newBlock.inputs)
+										newBlock.inputs = {};
+									if(newBlock.outputs)
+										newBlock.outputs = {};
+									if(newBlock.parameters)
+										newBlock.parameters = {};
+
+									updateBlock(newBlock, newGlobals);
+								}}
+							>
+								Reset
+							</Button>
+						</Col>
 					</FormGroup>
 				</FormGroup>
 				{ Object.entries(alg.contents.parameters || {}).length > 0 && <h5>Parameters</h5> }
diff --git a/conda/js/src/components/experiment/ExperimentEditor.spec.jsx b/conda/js/src/components/experiment/ExperimentEditor.spec.jsx
index 1c236bccf14c4e98b127bd2b5083c172af464b9e..88baef9d26e7a2a22ddfcd11426a4a81ffa76bcd 100644
--- a/conda/js/src/components/experiment/ExperimentEditor.spec.jsx
+++ b/conda/js/src/components/experiment/ExperimentEditor.spec.jsx
@@ -511,4 +511,105 @@ describe('<ExperimentEditor />', () => {
 			});
 		});
 	});
+
+	describe('Regression Tests', () => {
+		it(`clears the 'echo' & 'analysis' blocks from user/user/single/1/single_add`, () => {
+			const expName = 'user/user/single/1/single_add';
+			const saveFunc = sinon.spy();
+			const _updateFunc = (obj) => {
+				wrapper.setProps && wrapper.setProps({ data: obj });
+			};
+			const updateFunc = sinon.spy(_updateFunc);
+			const exp = testExps.find(exp => expName === exp.name);
+			const tc = testTcs.find(tc => expName.includes(tc.name));
+			wrapper = mount(
+				<C
+					data={getValidObj(exp, tc, [...normalBlocks, ...analyzerBlocks])}
+					experiments={[]}
+					normalBlocks={normalBlocks}
+					analyzerBlocks={analyzerBlocks}
+					datasets={datasets}
+					toolchain={tc}
+					saveFunc={saveFunc}
+					environments={envs}
+					updateFunc={updateFunc}
+				/>
+			);
+
+			expect(wrapper.props().data).to.have.property('name', expName);
+			expect(wrapper.props().data.contents).to.have.deep.property('blocks', {
+				'echo': {
+					'inputs': {
+						'in_data': 'in'
+					},
+					'algorithm': 'user/integers_add/1',
+					'outputs': {
+						'out_data': 'out'
+					},
+					parameters: {}
+				}
+			});
+
+			wrapper.find('svg #block_echo').simulate('click');
+			wrapper.update();
+			wrapper.find('.algorithm button.btn-secondary').simulate('click');
+			expect(updateFunc.callCount).to.equal(1);
+			expect(wrapper.props().data.contents).to.have.deep.property('blocks',
+				{ echo: {
+					inputs: {},
+					algorithm: '',
+					outputs: {},
+					parameters: {}
+				}}
+			);
+
+			wrapper.find('svg #block_analysis').simulate('click');
+			wrapper.update();
+			wrapper.find('.algorithm button.btn-secondary').simulate('click');
+			expect(updateFunc.callCount).to.equal(2);
+			expect(wrapper.props().data.contents).to.have.deep.property('analyzers',
+				{ analysis: {
+					inputs: {},
+					algorithm: '',
+					parameters: {}
+				}}
+			);
+
+			expect(wrapper.props().data).to.be.deep.equal({
+				'name': 'user/user/single/1/single_add',
+				'contents': {
+					description: '',
+					'analyzers': {
+						'analysis': {
+							inputs: {},
+							algorithm: '',
+							parameters: {}
+						}
+					},
+					'datasets': {
+						'set': {
+							'set': 'set',
+							'protocol': 'protocol',
+							'database': 'simple/1'
+						}
+					},
+					'blocks': {
+						'echo': {
+							algorithm: '',
+							inputs: {},
+							outputs: {},
+							parameters: {}
+						}
+					},
+					'globals': {
+						'queue': 'queue',
+						'environment': {
+							'version': '1.2.0',
+							'name': 'Python 2.7'
+						},
+					}
+				}
+			});
+		});
+	});
 });