actions are decoupled and use a callback