arthuroliveira
ServiceNow Employee

"Deep linking consists of using a uniform resource identifier (URI) that links to a specific location within an app rather than simply launching the app."

Wikipedia

DISCLAIMER This functionality isn't officially supported by service portal. Use at your own risk.

In this post we will continue from where we left off on Single page app on Service Portal   Part 1

Ui Router supports url history out of the box by appending hashes to the url but unfortunately it isn't possible within service portal.

For this demo we will implement our own workaround to accomplish the unique url functionality in our application by using get parameters (?) instead of hash (#).

Let's get to it!   All the functionality will live inside the client script of helloworld-uiview widget defined on the blog post part 1, lets see where we left off.

function ($state,$location) {

        if ($location.path().indexOf('editor') != -1) {

              return;

      }

      $state.go('homepage');

}

Let's start by loading all the parameters from the url, then removing $state.go('homepage') as we want to read from the url what state to load. Your code should look like this:

function ($state,$location) {

  if ($location.path().indexOf('editor') != -1) {

    return;

  }

  // returns an object with the url parameters

  var urlParams = $location.search();

  // Check if we have a variable called state from the url, if there is we load that state passing all the parameters

  if (urlParams.state) {

    $state.go(urlParams.state, urlParams);

    // If state isn't present in the parameters send user to default state

  } else {

    $state.go('homepage');

  }

}

Lets save our widget and go to /helloworld?state=detail and you should see the detail view

pasted image 0.png

But if you click on Go To Homepage View you are going to notice the url doesn't change. That's because we are not done yet. Let's go back to our uiview and add that functionality.

Next we are going to listen to a UI Router event called $stateChangeSuccess fired once the state transition is complete, every time it happens we are going to check it new state is different than old state (this can be improved to support same state with different parameters) if its different we are going to append state to parameters, in case the state wasnt specified in the url, and we manipulate   the url with angular $location service

function ($state,$location,$rootScope) {

  if ($location.path().indexOf('editor') != -1) {

    return;

  }

  // returns an object with the url parameters

  var urlParams = $location.search();

  // Check if we have a variable called state from the url, if there is we load that state passing all the parameters

  if (urlParams.state) {

    $state.go(urlParams.state, urlParams);

    // If state isn't present in the parameters send user to default state

  } else {

    $state.go('homepage');

  }

      $rootScope.$on('$stateChangeSuccess',

              function (event, toState, toParams, fromState, fromParams) {

                      if (toState.name != fromState.name) {

                              toParams.state = toState.name;

                              $location.search(toParams);

                      }

              }

      );

}

IMPORTANT: Please be careful when choosing your state parameters as they can conflict with service portal . e.g. Never use ID as SP relies on to define what page to load  

Save, test your portal and Voilí !

gif-generated.gif

NOTE: Your widget will reload every time the url changes (not 100% why other than $rootScope.$apply() being called somewhere else). There is a work around that, but this is topic for another time.

Thank you

Arthur Oliveira

3 Comments