hasGeocode didn't actually indicated if an endpoint has a value acquired from a geocoder. It was set to true when at least one call to a geocoder finished successfully, including getting an empty result. getRoute doesn't need to know what calls were made, it only needs coordinates. It also doesn't get to decide when to fetch coordinates, this is done in drag/change callbacks.
endpoint.setValue always calls changeCallback on its successful completion, with geocoding or without. This allows to decide when to call getRoute entirely from callbacks and event listeners.