Solvedui router RFC: Routing to Angular 1.5 .component()

I'd like to solicit some feedback from the community about routing to ng1 .component()s.


We recently added support for $scope.$resolve to the master and legacy branches. After the next release, you will be able to route to components, and access resolved data using a "component template", similar to ngRoute. Here's a proof of concept:

In angular2, however, we cannot use "component templates", and instead will be routing to a component class. In ui-router-ng2, you will supply the component's class in a state definition, probably something like this:

import {FooComponent} from "./fooComponent.js";
import {UIRouter, StateRegistry} from "ui-router-ng2";

let stateRegistry = uirouter.stateRegistry; // uirouter instance comes from somewhere
  name: 'foo',
  component: FooComponent, // Reference to the FooComponent class
  url: '/foo/:fooId'

I would like both ui-router for ng1 and for ng2 to have a similar look and feel when routing to components. Because of that, I'm considering allowing component: in a state definition for ui-router 1.0 for ng1.

There are a few mechanisms I've been tossing around as options for declaring a state's view should route to a component, and how to provide resolved data to that component. Note that we can't use constructor injection into a .component() to provide resolve data like we would for a normal ui-router template/controller combo, because we can not instantiate and manage the component lifecycle ourselves.

Given this angular 1.5 .component()

app.component('myComponent', {
  templateUrl: 'myComponent.html',
  controller: 'MyController',
  bindings: { input1: '<', input2: '<' }


Option 1: Keep it as-is. Use a template: and access data using $resolve.
$stateProvider.state('foo', {
  template: '<my-component input1="$" input2="$"></my-component>',
  url: '/foo/:fooId/:barId',
  resolve: {
    foo: ($stateParams, FooService) => FooService.get($stateParams.fooId),
    bar: ($stateParams, BarService) => BarService.get($stateParams.barId)
Option 2: Route to the component by name.

Require each component bindings to match a resolve name

$stateProvider.state('foo', {
  component: 'myComponent',
  url: '/foo/:fooId/:barId',
  resolve: {
    // input1 and input2 are same names as myComponent `bindings`
    input1: ($stateParams, FooService) => FooService.get($stateParams.fooId),
    input2: ($stateParams, BarService) => BarService.get($stateParams.barId)
Option 3: Route to the component by name + bindings mapping string

Allow resolve names to be mapped to component bindings using a DSL similar to ui-sref
The use case is that resolves may come from parent states, so may need to be mapped to the component bindings

$stateProvider.state('foo', {
  component: 'myComponent({ input1: foo, input2: bar })',
  url: '/foo/:fooId/:barId',
  resolve: {
    foo: ($stateParams, FooService) => FooService.get($stateParams.fooId),
    bar: ($stateParams, BarService) => BarService.get($stateParams.barId)
Option 4: Route to the component by name + bindings mapping object

Allow resolve names to be mapped to component bindings using an object
Again, the use case is that resolves may come from parent states, so may need to be mapped to the component bindings

$stateProvider.state('foo', {
  component: 'myComponent',
  bindings: { input1: "foo", input2: "bar" },
  url: '/foo/:fooId/:barId',
  resolve: {
    foo: ($stateParams, FooService) => FooService.get($stateParams.fooId),
    bar: ($stateParams, BarService) => BarService.get($stateParams.barId)
Option 5: Route to the component by name; Supply resolves via ui-view controller

For this option, the component has to be aware that it's inside of a ui-view. It requires the ui-view controller and accesses the resolves from there. The bindings object is not used.

app.component('myComponent', {
  templateUrl: 'myComponent.html',
  controller: function() {
    this.$onInit = function() {
      this.input1 = this.uiView.$;
      this.input2 = this.uiView.$;
  require: { uiView: '^uiView' }

$stateProvider.state('foo', {
  component: 'myComponent',
  url: '/foo/:fooId/:barId',
  resolve: {
    foo: ($stateParams, FooService) => FooService.get($stateParams.fooId),
    bar: ($stateParams, BarService) => BarService.get($stateParams.barId)

Option 6: Your option
46 Answers

✔️Accepted Answer

Done... options 1, 2, and 4 are supported.

This works for:

  • angular 1.5 .component()
  • angular 1.3+ and Todd Motto's .component() polyfill
  • angular 1.3+ bindToController directive
  • angular 1.2+ directive with scope: { foo: '=' } bindings

This code works by decorating states that have component: 'foo' with a templateProvider that builds a template that looks something like <foo my-data="::$resolve.myData"></foo>

Other Answers:

Option 1

This is what i'd go for. The UI router API is pretty comprehensive already so I wouldn't feel comfortable adding more things.

Option 2

I feel like there would be too much magic going on, especially when someone else picks up the code and doesn't know that resolves are autobound to the component's bindings

Option 3

Not a fan of micro DSLs unless they're unavoidable

Option 4

This looks to me like a better version of Option 2 but I still prefer Option 1

Option 5

Least favourable option in my opinion as it ties a component to UI router which renders it more or less unusable in other contexts which is the idea of a component

@siddharth-pandey I'm successfully using this config (with version 1.0.0-beta.1):

    $stateProvider.state('example', {
      url: '/example',
      component: 'example',
      resolve: {
        param1: param1,
        param2: param2

    angular.module('app').component('example', {
      bindings: {
        param1: '<',
        param2: '<'

I like option 2. It aligns more with how the components are dynamically loaded in Angular 2. How would these resolved values get set for the state component?

Also note that there is a polyfill for 0.2.18 based on my original route-to-component plunker:

Related Issues:

ui router typescript compilation errors "Cannot find name 'Promise'"
I recommend using typescript 2.0+ and adding to your tsconfig.json: This tells typescript to use the...
ui router RFC: Routing to Angular 1.5 .component()
Done.. options 1 2 and 4 are supported I'd like to solicit some feedback from the community about ro...
ui router Possibly unhandled rejection with Angular 1.5.9
1.6.0-rc.0 has the same problem and is solved via the same workaround: This error throwing ideally s...
ui router 1.0: Can't inject $transition$ into component's controller?
Yes this is a limitation of route to component $transition$ isn't a global service it's a locally sc...
ui router 1.0 URL change without changing state
@orangesoup did you try using dynamic parameters? I think it may be a good solution for you ...
ui router $onChanges does not trigger for 1-way binded resolved data
I founded another much more better solution for that issue:) Or I think I found. ...
ui router $stateChangeSuccess is fired before previous state $scope is destroyed in 0.2.16
If anyone needs it i made this little directive to globally force the old way to render on all ui-vi...
ui router Use Angular 1.5 components as routes
Heads up to anyone else who finds this plunkr above ☝️ it has a bug It needs to kebob the attribute ...
NG6 starter SyntaxError: Unexpected token import - on gulp component
Go to babel website Installation section Hello I'm trying to scaffold a component with a fresh clone...
material md-autocomplete: Cannot read property 'then' of undefined
That's a f ridiculous issue: isPromise = items && items.then; It makes me reconsider the experience ...
material layout-row with layout-wrap and percent flex widths, in Safari
@wsfuller the smaller shims above didn't work for me because of how heavily my team uses the angular...
material md-datepicker : calendar does not scroll automaticaly on selected date
@alanssoares Checked both the methods I found out the issue occurred inside the below method of Cale...
angular gridster2 How to dynamically add a component to this gridster?
I managed to get the basics of the gridster I can add dummy widgets and play around with them ...
laravel5 angular material starter Blank Page on fresh install
Hey @jadjoubran sorry i was caught up somewhere Thank you for your help I am getting a blank page af...
Angular Full Stack How to secure the api?
On the client side: You need to use the AuthHttp with class from angular2-jwt instead of the basic H...
material mdPanel issue after minification.
Thanks @oemmes Yep I managed to get it sorted in the service by following the correct inject structu...
axios Axios catch error returns javascript error not server response
I have exactly the same environment Try this: Modify from console.log(error) to console.log(
jest Bug: Watch mode on Linux causes a ENOSPC Node.js error
From my findings its not related to Jest at all On Linux (or Mac) we have a max number of system wat...
react RFClarification: why is setState asynchronous?
So here’s a few thoughts This is not a complete response by any means but maybe this is still more h...
react Preventing rerenders with React.memo and useContext hook.
This is working as designed There is a longer discussion about this in #14110 if you're curious ...
TypeScript Quick fix for 'unions can't be used in index signatures, use a mapped object type instead'
You can do this: Though Bar has no index signature (i.e. you can't then do (obj as Bar)[value as Foo...
webpack Cannot assign to read only property 'exports' of object '#<Object>' (mix require and export)
The code above is ok You can mix require and export You can't mix import and module.exports. ...
yarn Yarn Debian key expiry date updated (EXPKEYSIG 23E7166788B63E1E)
sudo apt-key adv --refresh-keys --keyserver also works to fix this issue for ma...
webpack How to exclude node_modules but one
@borm: a solution: Subj as example I create some module in another folder ( /projects/MY_MODULE ) MY...
yarn GPG error: stable InRelease NO_PUBKEY E074D16EB6FF4DE3
Doing curl -sS | sudo apt-key add - again was enough. ...
react React Fire: Modernizing React DOM
I love every of these points except the className change For latest status see an update from June 5...
angular Angular5.x lazyLoad problem, undefined is not a function
For others that find this issue via Google as i did: I had the same problem when trying to lazy load...
react starter kit How to call child component method from parent?
For example you can use Refs to Components approach like so: Demo:
react How should we set up apps for HMR now that Fast Refresh replaces react-hot-loader?
Okay here goes What Is Fast Refresh? It's a reimplementation of hot reloading with full support from...
svgo no such file or directory .svgo.yml
I noticed this problem with Yarn after someone had run yarn clean Deleting the .yarnclean file delet...
ant motion 模版代码下载下来导入到dva搭建的项目里面,启动时报错(npm start)
开启 JavaScript 就可以了 你好,我下载的Home项目引入到项目工程里面,为了方便,我全部放到了components下面,引入和基本流程没有问题。在家里的win10上面启动没有报错,在win...
react native gesture handler Unsupported top level event type "onGestureHandlerStateChange" dispatched
Because my navigators were created asynchronously the handler was registered too late and thus throw...
electron Requiring electron outside of main.js causes a TypeError
For anyone encountering this problem in the future and reading this thread Electron version: 1.3.5 O...
babel ReferenceError regeneratorRuntime is not defined
I had this issue using rollup with babel I just used this babel config to resolve it : ...
webpack nodejs 17: digital envelope routines::unsupported
workaround: Bug report What is the current behavior? Other relevant information: webpack version: 5....
meteor [] Error: ENFILE: file table overflow
I was getting the same after an upgrade to macOS Sierra Turns out macOS have a harsh limit on number...
webpack TypeError: Data must be a string or a buffer
Here is a workaround to help you to find the wrong import Using the latest 2.2.0 release although th...
vue router how to change document.title in vue-router?
Hi thanks for filling this issue You can simply define title in route's meta I really want set title...
babel eslint ESLint: 2.10.0 - Parsing error: Unexpected token =
parser: babel-eslint is OK! I'm using: and getting the following error: Parsing error: Unexpected to...
jest Error in Async Example: ReferenceError: regeneratorRuntime is not defined
This worked for me to fix ReferenceError: regeneratorRuntime is not defined in Jest: Then in .babelr...
jest babel-jest does not transpile import/export in node_modules when Babel 7 is used
For the record 🐛 Bug Report I started getting the dreaded SyntaxError: Unexpected token import erro...
react Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
You're exporting a React element not a component Change to Alternatively at the call site change <Co...
react Trigger simulated input value change for React 16 (after react-dom 15.6.0 updated)?
After some research of react source code I got a hack method for react 16: NOTICE: JUST A HACK ...
jest "Syntax Error: Invalid or unexpected token" with .png
I had the same error and resolved it by creating a assetsTransformer.js: Then add this to your jest ...
jest Watch mode stopped working on macOS Sierra
I had the same issue Upgrading watchman with brew install watchman to v4.7.0 fixed it. ...
material ui Module not found: Can't resolve 'material-ui-icons/Menu' Martial Next
For anyone else experiencing this issue: npm install @material-ui/icons
javascript How to configure React Native (Expo) project to use AirBnB's React rules via ESLint?
This is what I do in React and React Native: Step 1 Step 2 Backup your eslintrc file in case you wan...
yarn ERROR: There are no scenarios; must have at least one.
You've got the wrong yarn 😄 The Yarn you're executing comes from the cmdtest package: http://manpag...
webpacker localIdentName option moved in css-loader configuration
I faced same issue after upading css-loader but I solved it If you check css-loader readme ...
react native gesture handler Execution failed for task ':react-native-gesture-handler:compileDebugJavaWithJavac'
@zmGitHub npm i jetifier npx jetify fixed it for me on rn 0.6 I am fixing a incompatibility issue re...