diff --git a/src/ServerAPI.mjs b/src/ServerAPI.mjs index b12a7cef..cf7467ef 100644 --- a/src/ServerAPI.mjs +++ b/src/ServerAPI.mjs @@ -5,13 +5,13 @@ export class ServerAPI extends APIInterface { constructor(apiUrl) { super(); this.apiUrl = apiUrl; - this.fetchCanceler = new AbortController(); - this.cancelSignal = this.fetchCanceler.signal; } - async getChunkedData(viewTarget) { + // Each function takes a cancelSignal to cancel the fetch request if we will unmount component + + async getChunkedData(viewTarget, cancelSignal) { const json = await fetchAndParse(`${this.apiUrl}/getChunkedData`, { - signal: this.cancelSignal, // (so we can cancel the fetch request if we will unmount component) + signal: cancelSignal, method: "POST", headers: { "Content-Type": "application/json", @@ -21,9 +21,9 @@ export class ServerAPI extends APIInterface { return json; } - async getFilenames() { + async getFilenames(cancelSignal) { const json = await fetchAndParse(`${this.apiUrl}/getFilenames`, { - signal: this.cancelSignal, // (so we can cancel the fetch request if we will unmount component) + signal: cancelSignal, method: "GET", headers: { "Content-Type": "application/json", @@ -32,9 +32,9 @@ export class ServerAPI extends APIInterface { return json; } - async getBedRegions(bedFile) { + async getBedRegions(bedFile, cancelSignal) { const json = await fetchAndParse(`${this.apiUrl}/getBedRegions`, { - signal: this.cancelSignal, // (so we can cancel the fetch request if we will unmount component) + signal: cancelSignal, method: "POST", headers: { "Content-Type": "application/json", @@ -44,9 +44,9 @@ export class ServerAPI extends APIInterface { return json; } - async getPathNames(graphFile) { + async getPathNames(graphFile, cancelSignal) { const json = await fetchAndParse(`${this.apiUrl}/getPathNames`, { - signal: this.cancelSignal, // (so we can cancel the fetch request if we will unmount component) + signal: cancelSignal, method: "POST", headers: { "Content-Type": "application/json", @@ -56,8 +56,9 @@ export class ServerAPI extends APIInterface { return json } - async getChunkTracks(bedFile, chunk) { + async getChunkTracks(bedFile, chunk, cancelSignal) { const json = await fetchAndParse(`${this.apiUrl}/getChunkTracks`, { + signal: cancelSignal, method: "POST", headers: { "Content-Type": "application/json", @@ -66,10 +67,6 @@ export class ServerAPI extends APIInterface { }); return json; } - - abortRequests() { - this.fetchCanceler.abort(); - } } export default ServerAPI; \ No newline at end of file diff --git a/src/components/HeaderForm.js b/src/components/HeaderForm.js index a17c06cd..f52b2b7e 100644 --- a/src/components/HeaderForm.js +++ b/src/components/HeaderForm.js @@ -169,7 +169,8 @@ function viewTargetsEqual(currViewTarget, nextViewTarget) { class HeaderForm extends Component { state = EMPTY_STATE; componentDidMount() { - this.fetchCanceled = false; + this.fetchCanceler = new AbortController(); + this.cancelSignal = this.fetchCanceler.signal; this.api = this.props.APIInterface; this.initState(); this.getMountedFilenames(); @@ -177,11 +178,10 @@ class HeaderForm extends Component { } componentWillUnmount() { // Cancel the requests since we may have long running requests pending. - this.api.abortRequests(); - this.fetchCanceled = true; + this.fetchCanceler.abort(); } handleFetchError(error, message) { - if (!this.fetchCanceled) { + if (!this.cancelSignal.aborted) { console.log(message, error.name, error.message); this.setState({ error: error }); } else { @@ -298,7 +298,7 @@ class HeaderForm extends Component { getMountedFilenames = async () => { this.setState({ error: null }); try { - const json = await this.api.getFilenames(); + const json = await this.api.getFilenames(this.cancelSignal); if (!json.files || json.files.length === 0) { // We did not get back a graph, only (possibly) an error. const error = @@ -349,7 +349,7 @@ class HeaderForm extends Component { getBedRegions = async (bedFile) => { this.setState({ error: null }); try { - const json = await this.api.getBedRegions(bedFile); + const json = await this.api.getBedRegions(bedFile, this.cancelSignal); // We need to do all our parsing here, if we expect the catch to catch errors. if (!json.bedRegions || !(json.bedRegions["desc"] instanceof Array)) { throw new Error( @@ -379,7 +379,7 @@ class HeaderForm extends Component { getPathNames = async (graphFile) => { this.setState({ error: null }); try { - const json = await this.api.getPathNames(graphFile); + const json = await this.api.getPathNames(graphFile, this.cancelSignal); // We need to do all our parsing here, if we expect the catch to catch errors. let pathNames = json.pathNames; if (!(pathNames instanceof Array)) { @@ -545,7 +545,7 @@ class HeaderForm extends Component { console.log("New tracks have been applied"); } else if (this.state.bedFile && chunk) { // Try to retrieve tracks from the server - const json = await this.api.getChunkTracks(this.state.bedFile, chunk); + const json = await this.api.getChunkTracks(this.state.bedFile, chunk, this.cancelSignal); // Replace tracks if request returns non-falsey value if (json.tracks) { diff --git a/src/components/TubeMapContainer.js b/src/components/TubeMapContainer.js index bc7b9877..49bf4f6c 100644 --- a/src/components/TubeMapContainer.js +++ b/src/components/TubeMapContainer.js @@ -17,19 +17,19 @@ class TubeMapContainer extends Component { }; componentDidMount() { - this.fetchCanceled = false; + this.fetchCanceler = new AbortController(); + this.cancelSignal = this.fetchCanceler.signal; this.api = this.props.APIInterface; this.getRemoteTubeMapData(); } componentWillUnmount() { // Cancel the requests since we may have long running requests pending. - this.api.abortRequests(); - this.fetchCanceled = true; + this.fetchCanceler.abort(); } handleFetchError(error, message) { - if (!this.fetchCanceled) { + if (!this.cancelSignal.aborted) { console.error(message, error); this.setState({ error: error, isLoading: false }); } else { @@ -129,7 +129,7 @@ class TubeMapContainer extends Component { getRemoteTubeMapData = async () => { this.setState({ isLoading: true, error: null }); try { - const json = await this.api.getChunkedData(this.props.viewTarget); + const json = await this.api.getChunkedData(this.props.viewTarget, this.cancelSignal); if (json.graph === undefined) { // We did not get back a graph, even if we didn't get an error either. const error = "Fetching remote data returned error";