How to make axios synchronous

JavascriptAxios

Javascript Problem Overview


I'm using axios to check if an alias has not already been used by another in the database.

Problem: The ajax call doesn't wait for the server response to execute the remaining code.

The code looks like :

export default {
    data () {
        return {
            id: null,
            alias: null,
            valid: true,
        }
    },

    methods: {
        // triggered by the save button
        save () {
            this.valid = true;
            console.log('before checking');

            this.checkUniqueness();
            // other validations here

            if (this.valid) {
                console.log('3. checked valid, can save now');
                // save now
            }
        },

        checkUniqueness () {
            axios.get('/api/unique/alias', {
                params: {
                    id: this.id,
                    alias: this.alias,
                }
            })
                .then((response) => {
                    console.log('2. server response:' + response.data.unique)
                    this.valid = response.data.unique;
                });
        },

    },
}

The console shows the following result:

1. before checking
3. checked valid, can save now
2. server response:false

I cannot move the code of the save() method into .then because I do other validations on the input data such as alpha-numeric characters, minimum of characters...

I was able to delay the 3rd part (if (this.valid) {) using set setTimeout but it's not the best solution. what if the server takes more or less than the defined waiting time..

Question Is there a way to make this call sequential (1, 2, 3) instead of (1, 3, 2)?

Javascript Solutions


Solution 1 - Javascript

You can't (or at least really shouldn't) make it synchronous, so you'll need a different way forward.

One idea: return the promise from Axios:

checkUniqueness () {
    return axios.get('/api/persons/unique/alias', {
        params: {
            id: this.id,
            alias: this.alias,
        }
    })
    .then((response) => {
        console.log('2. server response:' + response.data.unique)
        this.valid = response.data.unique;
    });
}

and then call then() on it in save():

this.checkUniqueness()
.then((returnVal) => {
   // other validations here
  //  save
})
.catch(err => console.log("Axios err: ", err))

You could even do all your checking on one place if you returned the value from Axios's then() rather than setting the flag:

.then((response) => {
    console.log('2. server response:' + response.data.unique)
    return response.data.unique;
 });

then in save:

this.checkUniqueness()
.then((valid) => {
    if (valid) // do something
   // other validations here
   //  save
})

Solution 2 - Javascript

axios.get(...) returns a promise (a task that is promised for later) and you can wait the interpreter untill this promise ends with an await word in ES6+ :

let response = await axios.get(...)

but axios.get(...) returns the response while axios.get(...).then(...) returns what you intended to return. so if you dont return anything in then part it will be undefined:

let response = await axios.get(...).then() // nothing returns in then
console.log(response) // undefined

Solution 3 - Javascript

If you just do what JS docs (mozilla) show you can treat Axios as just another promise. Be careful about making the request synchronous bc it can freeze the UI and the rest of your app.

       async save () {
            this.valid = true;
            console.log('before checking');

            const isUnique = await this.checkUniqueness();
            console.log(isUnique); // => value waited for and returned from this.checkUniqueness()
            // other validations here

            if (this.valid) {
                console.log('3. checked valid, can save now');
                // save now
            }
        }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWarrioView Question on Stackoverflow
Solution 1 - JavascriptMarkView Answer on Stackoverflow
Solution 2 - Javascriptkia nasirzadehView Answer on Stackoverflow
Solution 3 - JavascriptTayskyView Answer on Stackoverflow