How to prevent the following Vue watch from triggering an infinite loop?

I have an object that looks like this:

visitorInfo: {
  name: {
    name: 'Name',
    value: '',
    isInvalid: false,
    errors: []
  },
  email: {
    name: 'Email address',
    value: '',
    validation: {
      isRequired: true
    },
    errors: []
  },
  phone: {
    name: 'Phone number',
    value: '',
    errors: []
  }
},

I'm using watch to add error messages when the value of the fields changes (e.g. when the user is typing in a form):

fields: {
  handler (fields) {
    Object.entries(fields).forEach(([key, value]) => {
      const field = fields[key]
      const isRequired = field.validation.isRequired && field.value
      if (isRequired) {
        field.errors.push({
          errorType: 'isRequired',
          message: 'This field is required.'
        })
      }
    })
  },
  deep: true
}

But as you can see there's a problem. This bit

field.errors.push({
  errorType: 'isRequired',
  message: 'This field is required.'
})

Will trigger an endless lop since it's modifying fields.

How to solve this issue?

Answers:

Answer

Since vue cannot detect if you directly modify an array element, this might help:

field.errors[field.errors.length] = {
  errorType: 'isRequired',
  message: 'This field is required.'
};

Another option would be to simply check if the error has already been reported:

if (isRequired && !field.errors.length) { ... }

The downside of this is that it will still trigger the watcher an unnecessary 2nd time.

Let me know how it goes.

Answer

I think you're watching the visitorInfo object,In this case, the modify of errors array will also trigger your watch when it changes,This leads to an infinite cycle

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.