switch to on.once so listener is cleaned up