<div id="app">
  <label for="thing">Name:</label>
  <input id="thing" type="text" />
  <p class="formname"></p> 
</div>
function Observable (subscriber) {
  return {
    subscribe: observer => subscriber(SafeObserver(observer))
  };
}

function fromEvent(element, eventType) {
  return Observable(function(observer) {
    var handler = ev => observer.next(ev);
    element.addEventListener(eventType, handler);
    
    observer.setUnsubscribe(function() {
      element.removeEventListener(eventType, handler);
    });
    
    return observer.unsubscribe;
  });
}

var inputText   = document.getElementById('thing');
var textDisplay = document.querySelector('.formname');

var input$      = fromEvent(inputText, 'keyup');
var unsubscribe = input$.subscribe(function(ev) {
  var value = ev.target.value;
  textDisplay.textContent = value;
  
  if(value === 'stop') {
    unsubscribe();
    inputText.value = '';
    textDisplay.textContent = '';
  }
});

// A "safety" wrapper
function SafeObserver (observer) {
  var safeObserver = {};
  var isSubscribed = true; //this will track our subscribtion state
  var _unsubscribe;

  // this is for convinience.
  // so we can subscribe like this: stream.subscribe(val => { ...some code })
  if(typeof observer === 'function'){
    observer = { next: observer };
  }

  safeObserver.next = function(value) {
    if (!isSubscribed || !observer.next) {
      return;
    }

    try {
      observer.next(value);
    } catch (e) {
      // we want to unsubscribe only if there is an error
      safeObserver.unsubscribe();
    }
  }

  safeObserver.error = function(err) {
    if (!isSubscribed || !observer.error) {
      return;
    }

    try {
      observer.error(err);
    } catch (e) {}

    // we will unsubscribe no matter what happens
    safeObserver.unsubscribe();
  }

  safeObserver.complete = function() {
    if (!isSubscribed || !observer.complete) {
      return;
    }

    try {
      observer.complete();
    } catch (e) {}

    // we will unsubscribe no matter what happens
    safeObserver.unsubscribe();
  }

  safeObserver.unsubscribe = function() {
    isSubscribed = false;

    if(_unsubscribe) {
      _unsubscribe();
    }
  }

  safeObserver.setUnsubscribe = function(unsub) {
    _unsubscribe = unsub;
  }

  return safeObserver;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.