diff --git a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue
index ecdee18d9..b931c6273 100644
--- a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue
+++ b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue
@@ -10,9 +10,9 @@
         class="margin-bottom-2"
       >
         <Dropdown
-          v-model="values.aggregation_type"
+          :value="values.aggregation_type"
           :error="fieldHasErrors('aggregation_type')"
-          @change="v$.values.aggregation_type.$touch"
+          @change="aggregationTypeChanged"
         >
           <DropdownItem
             v-for="aggregation in groupedAggregationTypes"
@@ -90,7 +90,7 @@ export default {
         field_id: null,
         aggregation_type: null,
       },
-      emitValuesOnReset: false,
+      skipFirstValuesEmit: true,
     }
   },
   computed: {
@@ -116,32 +116,6 @@ export default {
       return this.compatibleFields.map((field) => field.id)
     },
   },
-  watch: {
-    'values.aggregation_type': {
-      handler(aggregationType) {
-        if (
-          aggregationType !== null &&
-          aggregationType !== this.defaultValues.aggregation_type &&
-          this.values.field_id !== null
-        ) {
-          // If both the field and aggregation type
-          // are selected, check if they are still
-          // compatible.
-          const aggType = this.$registry.get(
-            'groupedAggregation',
-            aggregationType
-          )
-          const field = this.tableFields.filter(
-            (field) => field.id === this.values.field_id
-          )
-          if (!aggType.fieldIsCompatible(field)) {
-            this.values.field_id = null
-          }
-        }
-      },
-      immediate: true,
-    },
-  },
   mounted() {
     this.v$.$touch()
   },
@@ -171,6 +145,17 @@ export default {
       const fieldType = this.$registry.get('field', field.type)
       return fieldType.iconClass
     },
+    aggregationTypeChanged(aggregationType) {
+      this.values.aggregation_type = aggregationType
+      const aggType = this.$registry.get('groupedAggregation', aggregationType)
+      const field = this.tableFields.find(
+        (field) => field.id === this.values.field_id
+      )
+      if (field && !aggType.fieldIsCompatible(field)) {
+        this.values.field_id = null
+      }
+      this.v$.values.aggregation_type.$touch()
+    },
   },
 }
 </script>
diff --git a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue
index 133da433d..49eeb73fa 100644
--- a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue
+++ b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue
@@ -172,7 +172,7 @@ export default {
       },
       tableLoading: false,
       databaseSelectedId: null,
-      emitValuesOnReset: false,
+      skipFirstValuesEmit: true,
     }
   },
   computed: {
@@ -230,12 +230,15 @@ export default {
   watch: {
     dataSource: {
       async handler(values) {
+        this.setEmitValues(false)
         // Reset the form to set default values
         // again after a different widget is selected
         await this.reset(true)
         // Run form validation so that
         // problems are highlighted immediately
         this.v$.$touch()
+        await this.$nextTick()
+        this.setEmitValues(true)
       },
       deep: true,
     },
diff --git a/web-frontend/modules/core/mixins/form.js b/web-frontend/modules/core/mixins/form.js
index 68431bbe6..1ec7b8841 100644
--- a/web-frontend/modules/core/mixins/form.js
+++ b/web-frontend/modules/core/mixins/form.js
@@ -23,11 +23,15 @@ export default {
     return {
       // A list of values that the form allows. If null all values are allowed.
       allowedValues: null,
-      // By setting emitValuesOnReset to false in the form's component
-      // the values changed event won't be sent right after resetting the
-      // form
-      emitValuesOnReset: true,
-      isAfterReset: true,
+      // Setting to false make it possible to temporarily
+      // prevent emitting values when they change.
+      // Use setEmitValues(value) method to include children
+      // forms.
+      emitValues: true,
+      // Setting to true makes it possible to not
+      // emit values the first time values are set in
+      // the form.
+      skipFirstValuesEmit: false,
     }
   },
   mounted() {
@@ -38,7 +42,13 @@ export default {
   watch: {
     values: {
       handler(newValues) {
-        this.emitChange(newValues)
+        if (this.skipFirstValuesEmit) {
+          this.skipFirstValuesEmit = false
+          return
+        }
+        if (this.emitValues) {
+          this.emitChange(newValues)
+        }
       },
       deep: true,
     },
@@ -207,8 +217,6 @@ export default {
      * first level of children.
      */
     async reset(deep = false) {
-      this.isAfterReset = true
-
       for (const [key, value] of Object.entries(this.getDefaultValues())) {
         this.values[key] = value
       }
@@ -224,6 +232,15 @@ export default {
         child.reset()
       )
     },
+    /**
+     * Sets emitValues property also to child forms.
+     */
+    setEmitValues(value) {
+      this.emitValues = value
+      this.getChildForms((child) => 'setEmitValues' in child, true).forEach(
+        (child) => child.setEmitValues(value)
+      )
+    },
     /**
      * Returns if a child form has indicated it handled the error, false otherwise.
      */
@@ -241,13 +258,7 @@ export default {
       return childHandledIt
     },
     emitChange(newValues) {
-      if (this.emitValuesOnReset === true || this.isAfterReset === false) {
-        this.$emit('values-changed', newValues)
-      }
-
-      if (this.isAfterReset) {
-        this.isAfterReset = false
-      }
+      this.$emit('values-changed', newValues)
     },
   },
 }
diff --git a/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue b/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue
index 71f548e5f..a94b6d1f3 100644
--- a/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue
+++ b/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue
@@ -170,7 +170,7 @@ export default {
       },
       tableLoading: false,
       databaseSelectedId: null,
-      emitValuesOnReset: false,
+      skipFirstValuesEmit: true,
     }
   },
   computed: {
@@ -227,13 +227,16 @@ export default {
   },
   watch: {
     dataSource: {
-      handler(values) {
+      async handler(values) {
+        this.setEmitValues(false)
         // Reset the form to set default values
         // again after a different widget is selected
-        this.reset(true)
+        await this.reset(true)
         // Run form validation so that
         // problems are highlighted immediately
-        this.v$.$validate()
+        this.v$.$touch()
+        await this.$nextTick()
+        this.setEmitValues(true)
       },
       deep: true,
     },
diff --git a/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue b/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue
index 18c96d4df..c5d91d740 100644
--- a/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue
+++ b/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue
@@ -71,7 +71,7 @@ export default {
         title: '',
         description: '',
       },
-      emitValuesOnReset: false,
+      skipFirstValuesEmit: true,
     }
   },
   validations() {
@@ -98,8 +98,16 @@ export default {
   },
   watch: {
     widget: {
-      handler(value) {
-        this.reset(true)
+      async handler(value) {
+        this.setEmitValues(false)
+        // Reset the form to set default values
+        // again after a different widget is selected
+        await this.reset(true)
+        // Run form validation so that
+        // problems are highlighted immediately
+        this.v$.$touch()
+        await this.$nextTick()
+        this.setEmitValues(true)
       },
       deep: true,
     },