VueJS mengendalikan ralat dalam panggilan api pada komponen borang
P粉964682904
P粉964682904 2023-09-06 22:01:08
0
2
542

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粉964682904
P粉964682904

membalas semua(2)
P粉576184933

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
P粉180844619

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>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan