Search code examples
sapui5

Duplicate ID error when creating fragments in different Controllers


So... I'm building an application that is basically a CRUD. On this application, I have the following views / controllers: VisitEdit and RequestNew.

At the RequestNew controller, I have a function that handles the press of a button:

onRequestNewAddCustomerPress: function(oEvent) {
  if( !this.oAddCustomerDialog ){
    this.oAddCustomerDialog = sap.ui.xmlfragment("com.sap.lccapp.fragment.AddCustomer", this);
  }
  this.oAddCustomerDialog.openBy(oEvent.getSource());
},

And I have at this same Controller the onExit function. It is now empty, because I have made a LOT of test with the .destroy() function of this object (oAddCustomerDialog) and it continues popping up the error.


The problem is; on the VisitEdit controller, when I try to use the same dialog for the second time, with the same code as above, it shows the following error:

Adding element with duplicate id 'addCustomerNameField'

The ID "addCustomerNameField" is from my first element inside my fragment.

Although I have the 'if verification' on both methods and because it is in different controllers, the last 'if' that is being verified has the object (this.oAddCustomerDialog) undefined (BUT IT SHOULD NOT HAS UNDEFINED VALUE) and it is creating again the sap.ui.xmlfragment.


Fragment definition: http://dontpad.com/stackoverflowquestionsapui5


Solution

  • You can associate a unique ID when instantiating fragments. This way this unique ID will be prefix with the IDs of the control the fragment contains.

    So, two different codes will be:

    onRequestNewAddCustomerPress: function(oEvent) {
      if (!this.oAddCustomerDialog) {
        this.oAddCustomerDialog = sap.ui.xmlfragment("idOnNewRequest","com.sap.lccapp.fragment.AddCustomer", this);
      }
      this.oAddCustomerDialog.openBy(oEvent.getSource());
    },
    

    and then:

    onVisitEditAddCustomerPress: function(oEvent) {
      if (!this.oAddCustomerDialog) {
        this.oAddCustomerDialog = sap.ui.xmlfragment("idOnEdit","com.sap.lccapp.fragment.AddCustomer", this);
      }
      this.oAddCustomerDialog.openBy(oEvent.getSource());
    },
    

    Also, do check the following documentation topic: IDs in Declarative XML or HTML Fragments

    EDIT: If these fragments are being called from two different views, best to use the ID of the view. I would modify the code to instantiate fragment as below:

    this.oAddCustomerDialog = sap.ui.xmlfragment(this.getView().getId(), "com.sap.lccapp.fragment.AddCustomer", this);
    

    As of UI5 1.58, the factory function sap.ui.*fragment is deprecated. Please use Fragment.load instead!

    Fragment.load({
      id: this.getView().getId(),
      name: "com.sap.lccapp.fragment.AddCustomer",
      controller: this,
    }); // returns a promise