Navigating to Routes with Mandatory Parameters

Objectives
After completing this lesson, you will be able to:

After completing this lesson, you will be able to:

  • Navigate to a route that has a mandatory parameter

Routes with Mandatory Parameters

Suppose that when the user selects an entity (for example, customer, sales order) on an initial view, the application is to navigate to another view where details about the selected entity are displayed. To implement such a master-detail scenario, you can pass the data of the selected entity (for example, the associated Id) to the detail view via one or more parameters of the route. The parameter(s) can then be used by the detail view to identify the entity and fetch and display additional information.

SAPUI5 supports routes with mandatory and optional parameters, which are both defined in the pattern of a route. You specify a mandatory parameter for the pattern by placing the parameter in curly brackets.

In the example shown, a mandatory parameter named customerId is defined for the detail route. This makes, for example, the hashes detail/5 and detail/(00505604-4e85-1edd-818f-21e64b9cd2cf) match the route, while the hash detail/ does not. The patternMatched event of the route (see the next section) is then passed 5 or (00505604-4e85-1edd-818f-21e64b9cd2cf) as customerId in its arguments parameter.

Parameter Handling

The parameters of a route are set using the navTo method of the router. After the name of the route to be navigated to, a configuration object with the parameter values for the route is passed to this method as the second parameter.

The router always makes sure that mandatory parameters as specified in the route's pattern are set; otherwise an error is thrown.

Let's look at an example for setting parameter values and receiving parameter values, respectively.

Navigate to a Route with a Mandatory Parameter

Business Scenario

In the previous exercises, you added navigation from the Overview view to the Detail view to the scenario. So far, however, no customer-specific data is displayed on the Detail view. This will be implemented in this exercise: Additional data for the customer selected on the Overview view is to be displayed on the Detail view.

To do this, you will first add fields for customer-specific data to the UI of the Detail view. Then you will add a mandatory parameter to the detail route and use it to pass the Id of the customer selected on the Overview view to the Detail view during navigation. Finally, you will use the passed Id in the detail view controller to set the binding context for the Detail view. This allows the relative binding paths used on the view to be resolved and the corresponding customer data to be displayed on the view.

Template:Git Repository: https://github.com/SAP-samples/sapui5-development-learning-journey.git, Branch: sol/25_invalid_hashes
Model solution:Git Repository: https://github.com/SAP-samples/sapui5-development-learning-journey.git, Branch: sol/26_routing_with_parameters

Task 1: Extend the UI of the Detail View

Steps

  1. Open the i18n.properties resource bundle file from the i18n folder in the editor.

  2. Add the following key-value pairs to the i18n.properties file to define translatable labels for the customer fields that will be added in the next step:

    Code snippet
    customerNumberTitle=Customer Number
    streetTitle=Street
    postcodeTitle=Post Code
    cityTitle=City
    countryTitle=Country
    emailTitle=Email
    phoneTitle=Telephone
    discountTitle=Discount
    Copy code

    Result

    The i18n.properties resource bundle file should now look like this:
  3. Open the Detail.view.xml file from the webapp/view folder in the editor.

  4. Add the following object header to the content aggregation of the Page UI element to display fields with customer specific data on the view:

    Code snippet
    <ObjectHeader
      responsive="true"
      fullScreenOptimized="true"
      title="{Form} {CustomerName}">
      <attributes>
        <ObjectAttribute title="{i18n>customerNumberTitle}" text="{CustomerNumber}"/>
        <ObjectAttribute title="{i18n>streetTitle}" text="{Street}"/>
        <ObjectAttribute title="{i18n>postcodeTitle}" text="{PostCode}"/>
        <ObjectAttribute title="{i18n>cityTitle}" text="{City}"/>
        <ObjectAttribute title="{i18n>countryTitle}" text="{Country}"/>
        <ObjectAttribute title="{i18n>emailTitle}" text="{Email}"/>
        <ObjectAttribute title="{i18n>phoneTitle}" text="{Telephone}"/>                
        <ObjectAttribute title="{i18n>discountTitle}" text="{ path: 'Discount',
                                                              type: 'sap.ui.model.type.Float',
                                                              formatOptions: {minFractionDigits: 2, maxFractionDigits: 2}
                                                             } %"/>
      </attributes>
    </ObjectHeader>
    Copy code
    Note
    Relative paths are used here for binding the customer fields. As long as the context for this binding is not set, these paths cannot be resolved and hence no data can be displayed. In the next steps, you will therefore provide the corresponding binding context.

Result

The Detail view should now look like this:

Task 2: Pass the Id of the Customer Selected on the Overview View to the Detail View via a Mandatory Parameter of the detail Route

Steps

  1. Open the manifest.json application descriptor from the webapp folder in the editor.

  2. In the application descriptor, find the routes property in the routing configuration section of the sap.ui5 namespace:

    Code snippet
    "routes": [
      {
        "name": "overview",
        "pattern": "",
        "target": [
          "overview"
        ]
      },
      {
        "name": "detail",
        "pattern": "detail",
        "target": [
          "detail"
        ]
      }
    ]
    Copy code
  3. Change the value of the pattern property in the detail route to the following new value:

    Code snippet
    "pattern": "detail/{customerId}"
    Copy code
    Note
    With this, you add a mandatory parameter called customerId to the detail route. This parameter is used in the next step to pass the Id of the customer selected in the customer table on the Overview view to the Detail view.

    Result

    The routing configuration should now look like this:
  4. Open the Overview.controller.js file from the webapp/controller folder in the editor.

  5. Modify the implementation of the onNavToDetails event handler in the view controller as follows to trigger navigation to the Detail view and fill the customerId parameter of the detail route defined above with the Id of the selected customer:

    Code snippet
    onNavToDetails: function (oEvent) {
      var oItem = oEvent.getSource();
      var oRouter = this.getOwnerComponent().getRouter();
    
    
      oRouter.navTo("detail", {
        customerId: oItem.getBindingContext().getPath().substring("/UX_Customer".length)
      });
    }
    Copy code
    Note

    The oEvent parameter added to the onNavToDetails event handler is used to query the control that triggered the press event. The getSource method returns the ColumnListItem object from the customer table that was selected by the user. This item is used to get the Id of the associated customer by means of the binding. The obtained Id is then set for the customerId parameter of the detail route.

    For example, the method oItem.getBindingContext().getPath() returns the value /UX_Customer(00505604-4e85-1edd-818f-21e64b9cd2cf) for the customer SAP SE. The substring method removes /UX_Customer from this string and sets (00505604-4e85-1edd-818f-21e64b9cd2cf) as the value for the customerId parameter. In this way, the hash of the browser is set to detail/(00505604-4e85-1edd-818f-21e64b9cd2cf).

Result

The onNavToDetails event handler method should now look like this:

Task 3: Use the Customer Id Passed via Routing in the Detail View Controller to Set the Binding Context for the Detail View

Steps

  1. Open the Detail.controller.js file from the webapp/controller folder in the editor.

  2. Implement the onInit initialization method of the view controller as follows to register the _onObjectMatched method as an event handler for the patternMatched event of the detail route:

    Code snippet
    onInit: function () {
      var oRouter = this.getOwnerComponent().getRouter();
      oRouter.getRoute("detail").attachPatternMatched(this._onObjectMatched, this);
    }
    Copy code
    Note
    The _onObjectMatched method will be implemented in the next step. By registering it here, it will be called automatically when the current URL hash matches the pattern of the detail route.

    Result

    The view controller should now look like this:
  3. Implement the _onObjectMatched method as follows to set the context for the bindings on the Detail view:

    Code snippet
    _onObjectMatched: function (oEvent) {
      this.getView().bindElement("/UX_Customer" + oEvent.getParameter("arguments").customerId);
    }
    Copy code
    Note
    The oEvent parameter of the _onObjectMatched event handler method is used to query the value set in the Overview view controller for the customerId parameter of the detail route (for example, (00505604-4e85-1edd-818f-21e64b9cd2cf)). From this, the binding path for the corresponding customer is created (for example, /UX_Customer(00505604-4e85-1edd-818f-21e64b9cd2cf)) and this is set as the binding context for the Detail view via the bindElement method. Now all relative bindings on the Detail view can be resolved and the corresponding customer data can be displayed on the view.

    Result

    The view controller should now look like this:
  4. Test run your application by starting it from the SAP Business Application Studio.

    Caution
    Use the start-mock npm script to start the application.
    Make sure that the Detail view now displays data of the customer selected in the table on the Overview view.

    1. Right-click on any subfolder in your sapui5-development-learning-journey project and select Preview Application from the context menu that appears.

    2. Select the npm script named start-mock in the dialog that appears.

    3. In the opened application, check if the component works as expected.

Log in to track your progress & complete quizzes