diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_presenter.py b/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_presenter.py
index 5e60c311cf3310d4ca94f43ca6d0bea160a75e9f..af9cb6e7635048c2d9bf29dd3021083ff4d157a6 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_presenter.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_presenter.py
@@ -29,6 +29,17 @@ class FittingDataPresenter(object):
         if ws_name in self.model.get_loaded_workspaces():
             self.model.get_loaded_workspaces().pop(ws_name)
 
+    def rename_workspace(self, old_name, new_name):
+        if old_name in self.model.get_loaded_workspaces():
+            self.model.get_loaded_workspaces()[new_name] = self.model.get_loaded_workspaces().pop(old_name)
+
+    def clear_workspaces(self):
+        self.model.get_loaded_workspaces().clear()
+
+    def replace_workspace(self, name, workspace):
+        if name in self.model.get_loaded_workspaces():
+            self.model.get_loaded_workspaces()[name] = workspace
+
     def get_loaded_workspaces(self):
         return self.model.get_loaded_workspaces()
 
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_widget.py b/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_widget.py
index dd4cbd4254239b0a45af90a62ec22eea6dc9ca15..b50758a4d3db1079fe518124a1478c8de64e29fc 100644
--- a/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_widget.py
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/data_handling/data_widget.py
@@ -9,6 +9,8 @@ from Engineering.gui.engineering_diffraction.tabs.fitting.data_handling.data_mod
 from Engineering.gui.engineering_diffraction.tabs.fitting.data_handling.data_view import FittingDataView
 from Engineering.gui.engineering_diffraction.tabs.fitting.data_handling.data_presenter import FittingDataPresenter
 
+from Engineering.gui.engineering_diffraction.tabs.fitting.fitting_ads_observer import FittingADSObserver
+
 
 class FittingDataWidget(object):
     def __init__(self, parent, view=None):
@@ -20,8 +22,20 @@ class FittingDataWidget(object):
         self.model = FittingDataModel()
         self.presenter = FittingDataPresenter(self.model, self.view)
 
+        self.ads_observer = FittingADSObserver(self.remove_workspace, self.clear_workspaces,
+                                               self.replace_workspace, self.rename_workspace)
+
     def get_loaded_workspaces(self):
         return self.presenter.get_loaded_workspaces()
 
     def remove_workspace(self, workspace):
         self.presenter.remove_workspace(workspace)
+
+    def rename_workspace(self, old_name, new_name):
+        self.presenter.rename_workspace(old_name, new_name)
+
+    def clear_workspaces(self):
+        self.presenter.clear_workspaces()
+
+    def replace_workspace(self, name, workspace):
+        self.presenter.replace_workspace(name, workspace)
\ No newline at end of file
diff --git a/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/fitting_ads_observer.py b/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/fitting_ads_observer.py
new file mode 100644
index 0000000000000000000000000000000000000000..740aeba8f43cfd88e643ba681019ad6af738e365
--- /dev/null
+++ b/scripts/Engineering/gui/engineering_diffraction/tabs/fitting/fitting_ads_observer.py
@@ -0,0 +1,81 @@
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright © 2020 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+
+from mantid.api import AnalysisDataServiceObserver
+from functools import wraps
+import sys
+
+
+def _catch_exceptions(func):
+    """
+    Catch all exceptions in method and print a traceback to stderr
+    """
+
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        try:
+            func(*args, **kwargs)
+        except Exception:
+            sys.stderr.write("Error occurred in handler:\n")
+            import traceback
+            traceback.print_exc()
+
+    return wrapper
+
+
+class FittingADSObserver(AnalysisDataServiceObserver):
+    def __init__(self, delete_callback, clear_callback, replace_callback, rename_callback):
+        super(FittingADSObserver, self).__init__()
+        self.delete_callback = delete_callback
+        self.clear_callback = clear_callback
+        self.replace_callback = replace_callback
+        self.rename_callback = rename_callback
+
+        self.observeDelete(True)
+        self.observeRename(True)
+        self.observeReplace(True)
+        self.observeClear(True)
+
+    @_catch_exceptions
+    def deleteHandle(self, workspace_name, workspace):
+        """
+        Called when the ADS deletes a workspace, removes it from the dict of tracked workspaces.
+        :param workspace_name: name of the workspace
+        :param workspace: reference to the workspace (not used)
+        """
+        self.delete_callback(workspace_name)
+
+    @_catch_exceptions
+    def renameHandle(self, old_workspace_name, new_workspace_name):
+        """
+        Called when the ADS renames a workspace, updates the dict with the new name.
+        :param old_workspace_name: original name of the workspace
+        :param new_workspace_name: new name for the workspace
+        """
+        self.rename_callback(old_workspace_name, new_workspace_name)
+
+    @_catch_exceptions
+    def clearHandle(self):
+        """
+        Called when the ADS has been cleared, removes all data.
+        """
+        self.clear_callback()
+
+    @_catch_exceptions
+    def replaceHandle(self, name, workspace):
+        """
+        Called when the ADS has replaced a workspace with one of the same name.
+        Updates the workspace stored in the dict.
+        :param name: The name of the workspace.
+        :param workspace: A reference to the new workspace
+        """
+        self.replace_callback(name, workspace)
+
+    def unsubscribe(self):
+        self.observeDelete(False)
+        self.observeRename(False)
+        self.observeClear(False)