Skip to content

Make resolve results injectable in constructor #10838

Closed

Description

@robert-bor
[ ] bug report => search github for a similar issue or PR before submitting
[X] feature request
[ ] support request

First off, many thanks for your really great work on Angular. We love where this is going. Thanks!

Current behavior

Given a component:

@Component({
    template: require('./book-detail.html')
})
export class BookDetail implements OnInit {

    private book : Book;

    constructor(private route: ActivatedRoute) {}

    ngOnInit(): void {
        this.route.data.subscribe((data: { book: Book }) => {
            this.book = data.book;
        });
    }

}

And a resolver:

@Injectable()
export class BookDetailResolve implements Resolve<any> {
    constructor(private bookService: BookService) {}

    resolve(route: ActivatedRouteSnapshot): Promise<Book> {
        let id : number = _.toNumber(route.params['id']);
        return this.bookService.getBook(id);
    }
}

And a configuration in the router:

            path: ':id',
            component: BookDetail,
            resolve: {
              book: BookDetailResolve
            }

The way a book is passed to BookDetail is now done by having BookDetail implement OnInit and using the ngInit to read the book from the ActivatedRoute.

Expected/desired behavior

Ideally, it would be possible to have the following code:

@Component({
    template: require('./book-detail.html')
})
export class BookDetail {

    constructor(private book: Book) {}

}

In other words, the book as described in the route (and returned by BookDetailResolve) is injected directly into the constructor of BookDetail. This removes code which basically serves no purpose since resolve guarantees that all arguments are resolved prior to initializing the component. Code becomes predictable and the programming model is much easier to understand.

What is the motivation / use case for changing the behavior?

To reduce code which serves only as boilerplate and strive towards a cleaner and easier-to-understand codebase.

  • Angular version: 2.0.0-rc.5

Activity

  1. added
    featureLabel used to distinguish feature request from other issues
    on Aug 19, 2016
  2. DzmitryShylovich commented on Dec 21, 2016

    @DzmitryShylovich
    Contributor

    Very limited feature as to me. For example, u navigate from post/1 => post/2. Component will be reused, but resolver will fetch new data and what will happen next? We can't inject new data into already created component. So it's useless for all reused components.

  3. robert-bor commented on Dec 22, 2016

    @robert-bor
    Author

    Whether the feature is limited or not depends on whether you argue from component reuse. If you do, then you are right and the feature is indeed limited. But perhaps there is a way to see the bigger picture. Personally, I think component reuse in Angular is overrated. More so when it hampers the simplicity of the programming model. Is it really so objectionable to recreate the component for every route?

  4. Colorfulstan commented on Dec 22, 2016

    @Colorfulstan

    Not sure if im missing the point here, so excuse me if misunderstood the problem.
    Since I used ui-router for angularJS already I'm using ui-router for ng2 too and didn't really bother learning much about the original ng2 router so far.

    With ui-router you define your resolves within a state, which has a component associated to that state, that will be created when transitioning to the state.

    You then can use the resolves as Input within your component.
    Using Typescript this might look something like this then:

    export const BOOK_STATE: Ng2StateDeclaration = {
        name     : 'books.detail',
        url      : '/:id',
        component: BookDetail,
        resolve  : [
            {
                provide   : 'book',
                useFactory: function (bookService:BookService, bookId:number) {
                    return bookService.getBook(bookId)
                }, deps   : [BookService, 'id']
            }
        ]
    }
    
    @Component({
        template: require('./book-detail.html')
    })
    export class BookDetail {
    
        @Input() book : Book;
        constructor() {}
    }
    

    This allows to either input the Book as a resolve or as an attribute binding within the custom html tag, depending on which behaviour is needed (for example either as a Detail-page with it's own state, or a list of all book details).

  5. DzmitryShylovich commented on Dec 22, 2016

    @DzmitryShylovich
    Contributor

    @Colorfulstan Sounds like #9787

  6. added this to the Backlog milestone on Jan 23, 2018
  7. angular-robot commented on Jun 4, 2021

    @angular-robot
    Contributor

    Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

    Find more details about Angular's feature request process in our documentation.

  8. angular-robot commented on Jun 24, 2021

    @angular-robot
    Contributor

    Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.

    We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.

    You can find more details about the feature request process in our documentation.

  9. angular-automatic-lock-bot commented on Aug 23, 2021

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  10. locked and limited conversation to collaborators on Aug 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions