cari

Rumah  >  Soal Jawab  >  teks badan

VueJS mengendalikan ralat dalam panggilan api pada komponen borang

Saya mempunyai titik akhir pendaftaran mudah yang saya mahu membenarkan pengguna mendaftar dalam apl vue saya, saya juga ingin memaparkan ralat yang sesuai kepada klien vue dari bahagian belakang saya.

Struktur JSON ralat kelihatan seperti ini:

{
    "errors": {
        "Password": [
            "Password is required",
            "Minimum length of 8 characters is required"
        ],
        "UserName": [
            "Username is required",
            "Minimum length of 6 characters is required"
        ],
        "EmailAddress": [
            "Email Address is required",
            "Invalid Email Address"
        ],
        "ConfirmPassword": [
            "Confirm Password is required"
        ]
    }
}

Saya mempunyai composable dengan fungsi daftar seperti ini:

export default function useAuth() {

    let errors = ref({}) 

    const register = (request) => {

        errors = {}
        AuthService.register(request)
            .then(res => {
                console.log("res: "+ res)
            })
            .catch(err => {
                const errList = err.response.data.errors;
                errors = errList
                // Here i'm getting a reponse
                console.log(errors)

            })
    }
    return {
        register, errors
    }
}

Saya juga mempunyai komponen bentuk yang hanya bentuk ringkas dengan model v ditambah:

<script>
// Imports..
export default {
  components: {},
  setup() {

    const { register, errors} = useAuth();

    const request = {
      userName: "",
      emailAddress: "",
      password: "",
      confirmPassword: "",
    };


    const handleSubmit = () => {
        register(request);
        // empty object
        console.log(errors)
      
    };

    return {
      errors,
      request,
      handleSubmit
      
    };
  },
};
</script>

Dalam composable saya, saya boleh log keluar respons ralat seperti ini

Ralat respons

Saya cuba menyahdaftarkan ralat dalam komponen borang tetapi sekarang saya hanya mendapat objek kosong (saya menggunakan reaktif untuk mengendalikan objek ralat ini dalam composable)

Tindak balas objek kosong daripada item boleh gubah

P粉964682904P粉964682904446 hari yang lalu547

membalas semua(2)saya akan balas

  • P粉576184933

    P粉5761849332023-09-07 12:38:14

    Nampaknya anda memulangkan tatasusunan, bukan objek.

    Jadi untuk mendapatkan akses anda perlu lakukan errors[0].Password.

    Adakah anda akan menggunakan objek atau tatasusunan (mungkin berguna jika anda mempunyai berbilang ralat)?

    Jika tatasusunan dijangka dan anda perlu menyemak atribut Password untuk semua ralat, anda akan melakukan sesuatu seperti ini:

    errors.find(err => !!err.Password).Password
    

    balas
    0
  • P粉180844619

    P粉1808446192023-09-07 09:50:32

    Renungkan kod anda

    Terdapat banyak ralat di dalamnya, menyukarkan saya untuk memberikan jawapan ringkas yang sesuai dengan keperluan anda. Sebaliknya, saya dengan cepat menyusun coretan kod yang berfungsi mengikut prinsip anda. Melangkah ke hadapan, saya akan cuba menyerlahkan perkara yang perlu diberi perhatian dan memberikan beberapa nasihat yang baik untuk masa hadapan.

    - Respons menggunakan async function()可以等待Promise

    Tidak bagus (pada masa ini console.log 证明使用async jika anda ingin menggunakan hasilnya dengan segera)
    // YOUR CODE
    const handleSubmit = () => {
      register(request); // call PROMISE () 
      // empty object
      console.log(errors)
    };
    

    Ini tidak memberikan hasil serta-merta; ia mengambil sedikit masa untuk dijalankan pada benang yang berasingan. Akibatnya, skrip JavaScript bergerak ke hadapan hampir serta-merta. Biasanya ini akan mengakibatkan ralat jika anda ingin menggunakan hasilnya dengan segera kerana respons belum tiba lagi.

    Jadi apabila anda cuba mengakses errors 的新结果时,您会看到它是空的,即使在 console.log 之后,1-2 秒后,它不会再为空,因为 register() ia telah pun dilaksanakan.

    Okay
    // SUCCESSFULLY USING
    const handleSubmit = async () => {
      await register(request); // call PROMISE () AND WAIT response by await
      // empty object
      console.log(errors)
    };
    

    等待 - Tunggu proses tamat - Dokumentasi MDN
    异步函数 - 需要什么await Menggunakan - Dokumentasi MDN

    - Bagaimana untuk menggunakan ref() dengan VueJS?

    1.

    Simpan nilai yang disimpan oleh ref()reactive()compulated(), reactive(), compulated(), dsb. dalam pembolehubah yang tidak boleh diubah suai. Sentiasa gunakan const semasa mengisytiharkan pembolehubah ini.

    Maklumat lanjut - Jawapan StackOverflow

    Tak bagus
    // YOUR CODE
    let errors = ref({})
    
    Okay
    const errors = ref({})
    
    2.

    Anda menggunakan akhiran .value dalam satu kejadian dan bukan dalam yang lain. Nah, apa yang berlaku ialah hasil pembolehubah .value 后缀,而在另一实例中则不使用。嗯,情况是 ref() 变量的结果始终存储在 .value sentiasa disimpan dalam .value. Anda boleh memanipulasinya dengan sewajarnya.

    Tak bagus
    // YOUR CODE
    let errors = ref({})
    
    // and...
    errors = {...}
    
    Okay
    const errors = ref({})
    
    // and...
    errors.value = {...}
    

    Bagaimana cara menggunakan ref()? - Dokumentasi VueJS



    Contoh kod dengan logik yang digariskan

    Saya mengulas baris ini untuk memahami kod dengan lebih baik. Saya harap ini boleh difahami.

    /**
     ** Need more function for example
     ** !!! The vue is below !!!
     */
    
    // CDN Vue Import
    const { createApp, ref, computed } = Vue
    
    // isValideEmail() (JUST EXAMPLE FOR SNIPPET)
    // Helper function to validate email address
    function isValidEmail(email) {
      const emailRegex = /^\S+@\S+\.\S+$/;
      return emailRegex.test(email);
    }
    
    // AuthService (JUST EXAMPLE FOR SNIPPET)
    class AuthServiceClass {
      errors
      
      constructor() {
        this.errors = {};
      }
    
      register(inputs) {
        // Reset Errors
        this.errors = {};
        
        console.log(inputs)
        
        // Check the UserName field
        if (!inputs.userName) {
          this.errors.UserName = (this.errors?.UserName ?? []).concat("Username is required");
        }
        if (!inputs.userName || inputs.userName.length < 6) {
          this.errors.UserName = (this.errors?.UserName ?? []).concat("Minimum length of 6 characters is required");
        }
    
        // Check the EmailAddress field
        if (!inputs.emailAddress) {
          this.errors.EmailAddress = (this.errors?.EmailAddress ?? []).concat("Email Address is required");
        }
        if (!inputs.emailAddress || !isValidEmail(inputs.emailAddress)) {
          this.errors.EmailAddress = (this.errors?.EmailAddress ?? []).concat("Invalid Email Address");
        }
    
        // Check the Password field
        if (!inputs.password) {
          this.errors.Password = (this.errors?.Password ?? []).concat("Password is required");
        }
        if (!inputs.password || inputs.password.length < 8) {
          this.errors.Password = (this.errors?.Password ?? []).concat("Minimum length of 8 characters is required");
        }
    
        // Check the ConfirmPassword field
        if (!inputs.confirmPassword) {
          this.errors.ConfirmPassword = (this.errors?.ConfirmPassword ?? []).concat("Confirm Password is required");
        }
        
        // Return with Promise because its just a simulate your really AuthService.register
        return new Promise((resolve, reject) => {
          if (this.errors.length !== 0) {
            reject({ errors: this.errors });
          } else {
            resolve({ success: true, errors: null });
          }
        });
      }
    }
    // Import AuthService (JUST EXAMPLE FOR SNIPPET)
    const AuthService = new AuthServiceClass()
    
    // Declare useAuth() (JUST EXAMPLE FOR SNIPPET)
    function useAuth()
    {
        const errors = ref({}) 
    
        const register = async (request) => {
            await AuthService.register(request)
              .then(res => {
                console.log("AuthService Register Successfully Response", res)
              })
              .catch(err => {
                console.log("AuthService Register Error Response", err)
                const newErrors = err.errors;
                errors.value = newErrors
              })
        }
        
        return { register, errors }
    }
    
    /**
     ** !!!!!!
     ** Here's started vue code snippet
     */
    
    // Component.vue
    const app = createApp({
      setup() {
        // Get register() and errors Ref
        const { register, errors } = useAuth();
    
        // Declare Ref Object for inputs
        const request = ref({
          userName: "",
          emailAddress: "",
          password: "",
          confirmPassword: "",
        });
    
        // Declare Submit Function (async for Promise check !!!)
        const handleSubmit = async () => {
            console.log('') // just log
            console.log('Detect New Handle') // just log
    
            // call register() function with our value of inputs
            // wait answer by "await"
            await register(request.value);
    
            console.log('HandleSubmit - Check Error List', errors.value) // just log
        };
        
        // Just Extra Computed Value, not important
        // return true/false
        const hasError = computed(() => Object.keys(errors.value).length > 0)
        
        return { hasError, errors, request, handleSubmit }
      },
    }).mount('#app')
    .input {
      display: flex;
      flex-direction: column;
      gap: 2px;
      margin-bottom: 10px;
      max-width: 200px;
    }
    
    .error {
      color: red;
    }
    <!-- Component.vue -->
    
    <script src="https://unpkg.com/vue@3.3.4/dist/vue.global.prod.js"></script>
    
    <div id="app">
      <div>
        <!-- Display Errors -->
        <div v-if="hasError">
          <!-- errors is an object, so you can foreach its keys -->
          <div v-for="inputName of Object.keys(errors)">
            <span>{{ inputName }}:</span>
            <!-- name-array pairs can be directly printed as error messages -->
            <div v-for="errorMessage of errors[inputName]" class="error">
              {{ errorMessage }}
            </div>
          </div>
        </div>
        <!-- Inputs -->
        <!-- request is an object, so you can foreach its keys -->
        <div class="input" v-for="inputName of Object.keys(request)">
          <label>{{ inputName }}</label>
          <input v-model="request[inputName]" />
        </div>
        <!-- Submit Button -->
        <button @click="handleSubmit">Submit</button>
      </div>
    </div>

    balas
    0
  • Batalbalas