PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, October 14, 2022

[FIXED] How to abort requests with Axios AbortController?

 October 14, 2022     axios     No comments   

Issue

I'm trying to abort any/all previous Axios requests, using AbortController(): https://axios-http.com/docs/cancellation

FAILS: In my testing, previous queries do not get aborted.

The search experience still works as expected, but every request gets fully digested when user slams away on filters. Instead I want all previous requests to just be aborted.

I want to avoid building logic that uses storing/tracking requests, tokens and/or promises. I'm familiar with this stuff and could build it, but just want to avoid all that.

Is the Axios' AbortController intended for this purpose?

UPDATE (WORKS): Thx to @Oluwafemi, my setup is working.

Two things had to be changed:

  1. Set a new instance of AbortController() directly after the abort.
  2. The signal needs to be a third parameter going into the Axios function, and not part of the payload (unlike what you see in material online).

Side note: In addition, not included here is a debouncer wrapping my query function (in my app), which alongside this AbortController, makes for a good multi-layer management of outgoing/incoming comms with the API server.

(I redacted a bunch of methods/lines that aren't relevant)

export default class MySearch {

    constructor() {

        // ONE-TIME SETUP

        this.payload = null

        this.active = {
            q: "", // (Query) string e.g. "apples"
            facets: {}, // Objects, each with array of options e.g. { 'size': [ '2 x 2 in', '3 x 3 in' ]}, { 'artists': [ 'mike', 'john', 'jane' ] }
            page: null, // number e.g. 3
            sortBy: null // string, one of: "default" | "newest" | "price_asc" | "price_desc"
        }

        // Declaring this here. Good/bad?
        this.AxiosSearchController = new AbortController()
    }


    async query() {

        return new Promise( async (resolve, reject) => {

            // Abort any previous Axios request
            this.AxiosSearchController.abort()

            // Reinstantiate another instance of AbortController()
            this.AxiosSearchController = new AbortController()

            this.transformURL()

            let requestParams = {
                "page": this.active.page, 
                "sortBy": this.active.sortBy,
                "filter": this.active.facets,
            }

            // Here we tell Axios to associate the request with the controller.
            let AxiosSignal = {
                signal: this.AxiosSearchController.signal
            }

            axios.post('/api/search/' + this.active.q, requestParams, AxiosSignal)
            .then( response => {    
                this.payload = response.data    
                return resolve(response)
            })
            .catch( error => {
                console.error(error)
                return reject(error)
            })

        })
    }

}

Solution

Where AxiosSearchController is initialized for MySearch depends on if you want multiple instances of the MySearch to keep the same state of search or to maintain their own state of search.

When initialized in the constructor, each instance of MySearch has its own state of search like you have in your snippet.

1. Instance 1 initialized
2. Instance 2 initialized
3. Instance 3 initialized
4. Instance 1 performs request
5. Instance 2 performs request
6. Instance 3 performs request
7. Instance 1 aborts request
8. Instance 2 continues request till fulfillment
9. Instance 3 continues request till fulfillment

When initialized outside of the constructor, all instances of MySearch keep the same state of search.

1. Instance 1 initialized
2. Instance 2 initialized
3. Instance 3 initialized
4. Instance 1 performs request
5. Instance 2 performs request
6. Instance 1 has request aborted
7. Instance 3 performs request
8. Instance 2 has request aborted

Providing the signal property in the params argument is the proper format to set signal for the request for the axios library.

However, when aborting any previous request, AxiosSearchController.signal.aborted gets set to true.

Without resetting this state of the abort controller, you shouldn't be able to make any further requests after the signal is aborted the first time.

You need to initialize AxiosSearchController after aborting request for the previous search.

this.AxiosSearchController.abort();
this.AxiosSearchController = new AbortController();


Answered By - Oluwafemi Sule
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing