admin管理员组

文章数量:1418400

I am trying to register a new user in my application but am unable to check effectively whether or not the username exists - to be precise, the "check" is delayed by "one click"..

here is my ponent:

<template lang="html">
  <div class="main">
    <tw-navbar></tw-navbar>

    <div class="container-fluid">
     <div class="row">
       <tw-sidebar></tw-sidebar>

         <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
          <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
            <div class="container">
              <h1 class="h2">Add new customer</h1>
              <form class="w-50 m-auto">
              <div class="form-group">
                <label for="username">Username</label>
                <input type="username" class="form-control" id="username" placeholder="Enter username"
                        v-model.lazy="customerData.username">
              </div>
              <button type="submit" class="btn btn-primary" @click.prevent="addUser">Add</button>
            </form>
            </div>
          </div>
         </main>
     </div>
    </div>
  </div>
</template>

The script inside the Component

<script>
  import Navbar from './../navigation/Navbar.vue'
  import Sidebar from './../navigation/Sidebar.vue'
  import CustomerService from './../../services/CustomerService'
  import { EyeIcon, EyeOffIcon } from 'vue-feather-icons'

  export default {
      data() {
        return {
          customerData: {
                          username: '',
                        },
          usernameExists: null,
        }
      },
      methods: {
        addUser(){
            console.log("Before: "+this.usernameExists)

             CustomerService.checkUserExists(this.customerData.username)
                 .then(response => {
                  this.usernameExists = response.data['0'].exists
                  console.log("Inside: "+this.usernameExists)
                })
                .catch(e => console.log(e))

            console.log("After: "+this.usernameExists)
        },

      },
      ponents: {
        'tw-navbar': Navbar,
        'tw-sidebar': Sidebar,
        EyeIcon,
        EyeOffIcon
      }
    }
</script>

<style lang="css" scoped>
</style>

CustomerService is only calling and API which returns either 1(=exists) or O(=available) based on the DB query (=> SELECT count(*) as exists FROM users WHERE username = $1)

the API (BE) itself works perfectly fine

The problem is that FE is not waiting for API response and thus is "one click" delayed..

When I hit the ADD user button - the console gives me this output:

Before: null
After: null
Inside: 1

When I hit the ADD button again .. it gives me (delayed) correct results:

Before: 1
After: 1
Inside: 1

But of course, if I changed the username (to some nonexisting):

Before: 1
After: 1
Inside: 0

Inside, it returns that the username is available but in the app it seems like the username has been taken already (which is wrong

So as you can see, the Inside works fine, the problem is it's called as the last one ..

I should probably implement ASYNC/AWAIT - but that's where I am struggling .. Can someone help me out pls? By suggesting code changes I need to do? Thx a lot

I am trying to register a new user in my application but am unable to check effectively whether or not the username exists - to be precise, the "check" is delayed by "one click"..

here is my ponent:

<template lang="html">
  <div class="main">
    <tw-navbar></tw-navbar>

    <div class="container-fluid">
     <div class="row">
       <tw-sidebar></tw-sidebar>

         <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
          <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
            <div class="container">
              <h1 class="h2">Add new customer</h1>
              <form class="w-50 m-auto">
              <div class="form-group">
                <label for="username">Username</label>
                <input type="username" class="form-control" id="username" placeholder="Enter username"
                        v-model.lazy="customerData.username">
              </div>
              <button type="submit" class="btn btn-primary" @click.prevent="addUser">Add</button>
            </form>
            </div>
          </div>
         </main>
     </div>
    </div>
  </div>
</template>

The script inside the Component

<script>
  import Navbar from './../navigation/Navbar.vue'
  import Sidebar from './../navigation/Sidebar.vue'
  import CustomerService from './../../services/CustomerService'
  import { EyeIcon, EyeOffIcon } from 'vue-feather-icons'

  export default {
      data() {
        return {
          customerData: {
                          username: '',
                        },
          usernameExists: null,
        }
      },
      methods: {
        addUser(){
            console.log("Before: "+this.usernameExists)

             CustomerService.checkUserExists(this.customerData.username)
                 .then(response => {
                  this.usernameExists = response.data['0'].exists
                  console.log("Inside: "+this.usernameExists)
                })
                .catch(e => console.log(e))

            console.log("After: "+this.usernameExists)
        },

      },
      ponents: {
        'tw-navbar': Navbar,
        'tw-sidebar': Sidebar,
        EyeIcon,
        EyeOffIcon
      }
    }
</script>

<style lang="css" scoped>
</style>

CustomerService is only calling and API which returns either 1(=exists) or O(=available) based on the DB query (=> SELECT count(*) as exists FROM users WHERE username = $1)

the API (BE) itself works perfectly fine

The problem is that FE is not waiting for API response and thus is "one click" delayed..

When I hit the ADD user button - the console gives me this output:

Before: null
After: null
Inside: 1

When I hit the ADD button again .. it gives me (delayed) correct results:

Before: 1
After: 1
Inside: 1

But of course, if I changed the username (to some nonexisting):

Before: 1
After: 1
Inside: 0

Inside, it returns that the username is available but in the app it seems like the username has been taken already (which is wrong

So as you can see, the Inside works fine, the problem is it's called as the last one ..

I should probably implement ASYNC/AWAIT - but that's where I am struggling .. Can someone help me out pls? By suggesting code changes I need to do? Thx a lot

Share Improve this question asked Sep 26, 2020 at 13:29 Mr.PMr.P 1,2674 gold badges25 silver badges50 bronze badges 2
  • Does this answer your question? Babel 6 regeneratorRuntime is not defined – Ravi Commented Sep 26, 2020 at 13:31
  • hmm not really.. dunno how to implement that in the VueJS ponent .. can you share a sample code pls? – Mr.P Commented Sep 26, 2020 at 13:50
Add a ment  | 

3 Answers 3

Reset to default 4

just install core-js and regenerator-runtime and import it at the beginning of your main entry file.

npm i -S core-js@latest regenerator-runtime@latest

In my case, I added to main.js file because it is my main entry file on Webpack entry key.

// this is a remendation of babeljs (https://babeljs.io/docs/en/babel-polyfill)
// because @babel/polifill is deprecated
import 'core-js/stable'; 
import 'regenerator-runtime/runtime';

// also is possible
// import 'core-js'; 
// import 'regenerator-runtime';
...
// other imports

I hope this will be useful. Regards.

Ok I figured it out.. I simply didn't understand the async/await or promise chains at that time :)

so the answer is very simple:

AsyncAwait solution:

async addUser(){
        console.log("Before: ")

        const isUnique = await CustomerService.checkUserExists(this.customerData.username)
        if(!isUnique) throw new Error("Oops already exists")    

        console.log("After: ")
    },

Promise chaining:

addUser(){
        console.log("Before: ")

        CustomerService.checkUserExists(this.customerData.username)
           .then(data => {
                if(!data.isUnique) throw new Error("Oops already exists")
                console.log("After: ") 
                return //-- go to another then() section -> continue in the promise chain
           })
           .then(() => {
                console.log("After the after :)")
                return //-- go to another then() section -> continue in the promise chain
           })
           .then(() => {
                console.log("After the after-after :)")
           })
           .catch(error => {
                 console.log("Error:",error)
           })
           
    },

Simple solution

1.) Run npm install regenerator-runtime

2.) Add import 'regenerator-runtime'; to your webpack entry file (usually app.js or main.js)

本文标签: javascriptVueJS async awaitregeneratorRuntime is not definedStack Overflow