0

I'm using ui-router with Angular.js creating a documentation CMS that will run locally (ie not open to other clients).

We need both Japanese and English versions of each documentation page, but the translation of the Japanese pages is still ongoing, so I would like the routing to "fallback" to the English page if the Japanese doesn't exist, and finally to a "404" page if the English page route fails.

What I have below works (minus the "404" fallback), but it's messy, since the templateURL: function in the docs.display state is also repeated in a 'tutorials' section, etc.

.config(function ($stateProvider) {
  $stateProvider
    .state('docs', {
      url: '/docs',
        views: {
          '': {
            controller: 'docuCtrl',
            template: '<div class="row"><div class="col-sm-3"><div ui-view="tableContents"></div></div><div class="col-sm-9"><div ui-view="pageContents"></div></div></div>'
          },
          'tableContents@docs': {
            controller: 'docuCtrl',
            templateUrl: '/assets/partials/partial-toc.html'
          },
          'pageContents@docs': {
            controller: 'docuCtrl',
            templateUrl: '/assets/partials/partial-landing.html'
          }
        }
      })
      .state('docs.display', {
        url: "/:lang/:file",
          views: {
            'pageContents@docs': {
              templateUrl: function ($transition) {
                if ($transition.file) {
                  var url = 'http://localhost:9000/docs/' + $transition.lang + '/' + $transition.file;
                  var request = new XMLHttpRequest();
                  request.open('HEAD', url, false);
                  request.send();
                  if (request.status !== 200) {
                    if ($transition.lang === 'en') {
                      return '/docs/jp/' + $transition.file;
                    }
                    if ($transition.lang === 'jp') {
                      return '/docs/en/' + $transition.file;
                    }
                  } else {
                    return '/docs/' + $transition.lang + '/' + $transition.file;
                  }
                }
              }
            }
          }
        })

What I want to do is encapsulate that into a service and inject that service into the templateUrl but that is not working.

So, I want to do something like this:

.state('docs.display', {
  url: "/:lang/:file",
    views: {
      'pageContents@docs': {
        templateUrl: function (fallbackServ) {
          fallbackService.checkLink('docs', $transition.lang, $transition.file).then(function (response) {
            return response;
          });
        }
      }
    }
  })

But I get the error "fallbackService.checkLink is not a function"

Is it possible to do this in a service?

rrd
  • 5,789
  • 3
  • 28
  • 36

1 Answers1

0

Injecting a service into a config block doesn't work out of the box, but it can be done.

have a look at this answer

Guy Yogev
  • 861
  • 5
  • 14