Skip to content
This repository has been archived by the owner on Oct 16, 2023. It is now read-only.

Commit

Permalink
Improve reliability of 'View job' link navigation
Browse files Browse the repository at this point in the history
By listening for known map/state events to complete, and then directing the browser to the job URL. This replaces the use of an arbitrary 800ms timeout which was hacky but in most cases seemed to work. By taking the time to understand the flow of events, we've been able to build a better solution.
  • Loading branch information
Ollie Treend authored and jsmcgd committed Jul 9, 2018
1 parent a80ea5b commit d7e3c82
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 43 deletions.
41 changes: 23 additions & 18 deletions web/app/themes/ppj/src/vue/FindAJob.vue
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
:selected="job.locationId == selectedLocationId"
:title="job.title"
:url="job.url"
@jobLinkClickedEvent="navigatingToJobSite"
@job-link-clicked="loadJobUrl"
>
</job-summary>
</li>
Expand Down Expand Up @@ -452,17 +452,19 @@
this.updateSearchTermMarker(this.searchTerm.latlng.lat, this.searchTerm.latlng.lng);
}
// Use the bounds_changed event listener to persist the state after the map has fully loaded.
// The first bounds_changed event will be ignored as it is always fired on map creation
// and we don't want to persist the default state
let ignoreBoundsChanged = true;
this.map.object.addListener('bounds_changed', debounce(() => {
if (ignoreBoundsChanged) {
ignoreBoundsChanged = false;
} else {
// The first map 'idle' event will be triggered whilst initialising the map,
// by us either panning the map to England or restoring the bounds from the URL state.
// We don't want to persist this default state.
// Therefore we don't want to update the current state for this first event.
let ignoreFirstIdle = true;
this.map.object.addListener('idle', () => {
if (ignoreFirstIdle) {
ignoreFirstIdle = false;
}
else {
this.map.currentBounds = this.map.object.getBounds();
}
}, 250));
});
},
createMap() {
Expand Down Expand Up @@ -688,16 +690,19 @@
this.showPage(this.numberOfResultPages - 1);
},
activateScreenOverlay() {
loadJobUrl(url) {
this.screenOverlayActive = true;
},
deactivateScreenOverlay() {
this.screenOverlayActive = false;
},
navigatingToJobSite() {
this.activateScreenOverlay();
// We want to navigate to the job URL once the map has stopped moving
// and after Vue has finished processing the DOM (on 'next tick')
// Prior to this, the map's bounds will still be changing and therefore
// history.replaceState will still be called.
// It's only safe to navigate away from the page after that has happened.
google.maps.event.addListenerOnce(this.map.object, 'idle', () => {
this.$nextTick(() => {
window.location.href = url;
});
});
}
},
Expand Down
27 changes: 2 additions & 25 deletions web/app/themes/ppj/src/vue/JobSummary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<a class="job-summary__link"
v-if="url"
:href="url"
@click="linkClickHandler()"
@click.prevent="linkClickHandler"
>
view job & apply
</a>
Expand Down Expand Up @@ -50,37 +50,14 @@
},
linkClickHandler: function() {
this.$emit('jobLinkClickedEvent');
this.pushViewJobClickEventToGtm();
/*
* NB: This is fix for the issue whereby clicking the 'View Job & Apply' link
* in Chrome did not navigate to the location specified by the href attribute
*
* This is probably due to a race condition caused by some combination of
* the linked to site responding slowly and the triggered history.replaceState action
* happening asynchronously.
*
* By adding the following timeout function to explicitly navigate to the supplied url,
* the correct navigation happens, despite the fact that the timeout is set to happen
* zero milliseconds later. Presumably in a single threaded environment, the earliest
* this function gets executed is after the replaceState operation.
* UPDATE: with the new loading spinner changes, it is now necessary to wait around 800
* milliseconds.
*
* This went unnoticed for a while due to Google Tag Manager presumably slowing
* some part of the execution sufficiently such that this race condition didn't exist.
*/
setTimeout(()=>{
window.location.href = this.url;
}, 800);
this.$emit('job-link-clicked', this.url);
},
},
computed: {
formattedDistance: function () {
let distanceStr = '';
const suffix = ' miles';
Expand Down

0 comments on commit d7e3c82

Please sign in to comment.