0

I have an ui.router state in which I need to resolve some data, but it seems to resolve after loading the controller and before loading the template.

State definition looks like:

$stateProvider
         .state( 'route', {
            url: '/update/:id',
            template: '<update order="$resolve.order"></update>',
            resolve: {
                order: function( OrdersService, $stateParams ) {
                    return OrdersService.get( $stateParams.id ).$promise
                }
            }
        } )

Component:

const Update = {
    bindings: {
       order: "<"
    },
    controller,
    template
};

angular.module( 'app' )
    .component( 'update', Update );

Controller:

export default class UpdateCtrl {
    constructor(){
         ...
         console.log(this.order);
         ...
    }
}

OrdersService:

class OrdersService {
    constructor( $resource, api_name ) {
        this.$resource = $resource( api_name + '/orders/:id', { id: '@id' }, {
            get: { method: 'GET' }
        } );
    }
    get( orderId ) {
        return this.$resource.get( { orderId } );
    }
}
angular.module( 'app' )
    .factory( 'OrdersService', [
        '$resource',
        'api_name',
        ( $resource, api_name ) => new OrdersService( $resource, api_name )
    ] );

All imports are fine, and I still get following from controller, and full data in template

console.log(this.order) // undefined

P.S. I found some strange behavior when I call console.log(this.order,this) in the controller constructor.
It prints to console

undefined OrderUpdateCtrl
             $stateParams:Object
             OrdersService:OrdersService
             order:Resource // full resolved object
             __proto__:Object

3 Answers3

0

Has described in official documentation:

You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.

So you need to inject order in ui-router state's controller.

Andrea
  • 3,370
  • 1
  • 17
  • 25
  • 1
    injecting into component controller gives an `Unknown provider: orderProvider <- order` error injecting into a state controller gives no result when passing data to component through bindings – Onefivefournine Jan 17 '17 at 15:22
  • Correct. Injecting into a component controller won't work because there is no `order` service. If you inject into the state controller, add the line `this.order = order` to the constructor to make the data available to a component through bindings. See my answer below. – Byron Jones Jan 17 '17 at 15:53
  • I have updated my answer, you need to inject `order` in the controller of ui-router state `'route'` and then pass it to directive's controller . – Andrea Jan 17 '17 at 16:22
  • @ByronJones @Andrea, unfortunately this doesn't work, I injected `order` into state controller and then through bindings to the component, and somehow it's still not available in controller `template: '',` `controller: function( order ) {` `this.order = order;` `},` `controllerAs: 'resCtrl',` `resolve: { ... }` – Onefivefournine Jan 18 '17 at 08:31
  • @Onefivefournine, my guess is that you are still having problems with your controller/component; see my updated answer. – Byron Jones Jan 19 '17 at 17:09
0

The behavior you are observing makes sense. Your console.log call is inside the controller's constructor, and you do not provide an argument that Angular can use to inject order, making available to the constructor.

Angular is in fact resolving order before newing up the controller, but it can't add $resolve.order to the controller until after the controller object exists. So order won't exist in the constructor function, but will exist before rendering the template.

You also have a problem with your OrdersService. Your get function never passes the id parameter (it passes orderId, which isn't defined in your route). In all likelihood, your API never gets called correctly. Change the parameter object to {id: orderId}, and you should be in good shape.

Byron Jones
  • 702
  • 5
  • 11
0

Found answer here
How to wait for binding in Angular 1.5 component (without $scope.$watch)

I should have just use the $onChanges hook to wait when promise is resolved

Community
  • 1
  • 1