# Change a value programmatically and emit change

**URL:** <https://jsonforms.discourse.group/t/change-a-value-programmatically-and-emit-change/2590>\
**Category:** General\
**Tags:** vue\
**Created:** [February 5, 2025, 6:17am UTC](https://jsonforms.discourse.group/t/change-a-value-programmatically-and-emit-change/2590 "2025-02-05T06:17:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![bsatwork](https://avatars.discourse-cdn.com/v4/letter/b/e19b73/32.png) [@bsatwork](https://jsonforms.discourse.group/u/bsatwork)\
**Post date:** [February 5, 2025, 6:17am UTC](https://jsonforms.discourse.group/t/change-a-value-programmatically-and-emit-change/2590/1 "2025-02-05T06:17:58Z")

</div>

Good Morning,

I’m using Vue3 and:

```auto
"@jsonforms/core": "^3.4.1", 
"@jsonforms/vue": "^3.4.1",
"@jsonforms/vue-vanilla": "^3.4.1" 

```

I have a CustomRenderer for Text Cells. I insert a Button, if the Button is clicked a backend request gets fired and delivers a result. This result should be the new value of the Input.

Now, im receiving the result and set the `control.data.value` to the result but the change event won’t trigger so the error still shows and the value does not render properly

Component

```HTML
<template>
  <CustomInputWrapper
    :label="controlWrapper.label"
    :errors="controlWrapper.errors"
    :id="controlWrapper.id"
    :styles="styles"
    :applied-options="appliedOptions"
    :is-focused="isFocused"
    :description="controlWrapper.description"
    :required="controlWrapper.required"
  >
    <div class="wrapper-element pr-1" :class="isFocused ? 'ring-1 ring-[--md-sys-color-on-primary-container]' : ''">
      <input
        :id="control.id + '-input'"
        class="input-element rounded-md focus:ring-transparent"
        :value="control.data"
        :disabled="!control.enabled"
        :autofocus="appliedOptions.focus"
        :placeholder="appliedOptions.placeholder"
        @change="onChange"
        @focus="isFocused = true"
        @blur="isFocused = false"
      />
      <button
        v-show="hasError"
        :class="[
          'fix-button rounded-md',
          fixState === 'error' ? '!bg-[--md-sys-color-error-container] !text-[--md-sys-color-on-error-container]' : '',
          fixState === 'success'
            ? '!bg-[--md-sys-color-error-container] !text-[--md-sys-color-on-error-container]'
            : '',
        ]"
        @click="handleFix"
      >
        <span v-if="!fetchingFix">
          <ArrowPathIcon
            :class="fixState === 'error' ? 'text-red' : 'text-green'"
            v-if="controlWrapper.id.includes('catenaXId')"
            class="h-5"
          ></ArrowPathIcon>
          <SparklesIcon v-else-if="errorType === 'required'" class="h-5"></SparklesIcon>
          <WrenchIcon v-else-if="errorType === 'pattern'" class="h-5"></WrenchIcon>
        </span>
        <Spinner class="h-5 w-5" v-if="fixState === 'processing' && fetchingFix"></Spinner>
      </button>
    </div>
  </CustomInputWrapper>
</template>

```

Component Logic:

```TS
import { type ControlElement } from '@jsonforms/core'
import { ArrowPathIcon, WrenchIcon, SparklesIcon } from '@heroicons/vue/24/outline'

import { rendererProps, useJsonFormsControl } from '@jsonforms/vue'
import { useVanillaControl } from '@jsonforms/vue-vanilla'
import CustomInputWrapper from '@/components/JsonForms/CustomInputWrapper.vue'
import type { ErrorResponse } from '@/models/semanticModel'
import { type Ref, ref, watch } from 'vue'
import useSemanticModels from '@/composables/useSemanticModels'
import { replaceDotsWithSlashes } from '@/utils/helper'
import Spinner from '@/components/Spinner.vue'

const { selectedModel } = useSemanticModels()

const props = defineProps({
  ...rendererProps<ControlElement>(),
})

const { controlWrapper, onChange, isFocused, control, styles, appliedOptions } = useVanillaControl(
  useJsonFormsControl(props),
  (target) => {
    console.log(target.value)
    return target.value || undefined
  }
)
type FixState = 'pending' | 'processing' | 'error' | 'success'
type ErrorTypes = 'pattern' | 'required' | 'undefined'

const hasError = ref(false)
const errorType: Ref<ErrorTypes> = ref('undefined')
const fetchingFix = ref(false)
const fixState = ref<FixState>('pending')

watch(
  control,
  (nv) => {
    const errors = control.value.errors
    hasError.value = errors.length > 0
    if (hasError.value) {
      errorType.value = errors.includes('required') ? 'required' : errors.includes('pattern') ? 'pattern' : 'undefined'
    }
  },
  { deep: true }
)

const emit = defineEmits(['change'])
const handleFix = (event: Event) => {
  const errorResponse: ErrorResponse = {
    property_key: control.value.id,
    property_path: replaceDotsWithSlashes(control.value.path),
    property_value: control.value.schema!,
    error: control.value.errors,
    value: control.value.data,
  }
  fetchingFix.value = true
  fixState.value = 'processing'

  selectedModel.actions
    .fix(errorResponse, selectedModel.model.value!)
    .then((r) => {
      console.log(control.value.data, r.data.value)
      control.value.data = r.data.value
      emit('change')
      fixState.value = 'success'
    })
    .catch((err) => {
      console.log(err)
      fixState.value = 'error'
    })
    .finally(() => {
      fetchingFix.value = false
    })
}

```

I need to trigger the onChange event so it triggers the validation and shows the inserted value. How would i do that ? is there a best practice?

Thanks in advance.

Cheers,  
Benedikt

---

<div class="post-metadata">

**Author:** ![bsatwork](https://avatars.discourse-cdn.com/v4/letter/b/e19b73/32.png) [@bsatwork](https://jsonforms.discourse.group/u/bsatwork)\
**Post date:** [February 5, 2025, 6:34am UTC](https://jsonforms.discourse.group/t/change-a-value-programmatically-and-emit-change/2590/2 "2025-02-05T06:34:33Z")

</div>

Nevermind, apparently here is a possible fix.

```TS
selectedModel.actions
    .fix(errorResponse, selectedModel.model.value!)
    .then((r) => {
      console.log(control.value.data, r.data.value)
      control.value.data = r.data.value
      onChange({ target: { value: r.data.value } }) // this one 
      fixState.value = 'success'
    })
    .catch((err) => {
      console.log(err)
      fixState.value = 'error'
    })
    .finally(() => {
      fetchingFix.value = false
    })

```

But is there a better way to do it?

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [February 10, 2025, 8:56am UTC](https://jsonforms.discourse.group/t/change-a-value-programmatically-and-emit-change/2590/3 "2025-02-10T08:56:07Z")

</div>

Hi @bsatwork,

Your fix contains the correct approach by invoking `onChange` which in turn invokes `handleChange` which invokes a state update. To avoid the weird `target:value` nesting, you could also invoke `handleChange` directly.

You do not need to update the `control.value.data`, this will be updated automatically via the `onChange` state update.
