Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router Lifecycle OnActivate not waiting for the promise before displaying the template #4984

Closed
youknowriad opened this issue Oct 28, 2015 · 6 comments

Comments

@youknowriad
Copy link

Hi,

I have a component that looks like this

@Component({
    selector: 'client'
})

@View({
    directives: [ NgIf ],
    template: `
        <div class="pad">
            <h1>Client : {{ client.name }}</h1>
        </div>
    `
})

export class ClientShow {
    client: Client;
    routeParams: RouteParams;
    repository: ClientRepository;
    constructor(repository: ClientRepository, routeParams: RouteParams) {
        this.repository = repository;
        this.routeParams = routeParams;
    }
    onActivate() {
        return this.repository.find(this.routeParams.params['id']).then(client => {
            this.client = client;
        });
    }
}

And it seems that the template is displayed before the onActivate lifecycle hook promise is resolved.
I'm getting the following error : EXCEPTION: TypeError: Cannot read property 'name' of undefined in [null] at first, and after the promise is resolved, the name is displayed correctly.

Is this the desired behaviour ? May be I'm missing something, It's not easy to find documentation about theses lifecycle hooks for now.

Thanks a lot

@brandonroberts
Copy link
Contributor

@youknowriad You need to set client to an initial value, or put an ng-if in your template to make sure client is defined first. The component has already been loaded, then the onActivate happens.

@Component({
    selector: 'client'
})

@View({
    directives: [ NgIf ],
    template: `
        <div class="pad" *ng-if="client">
            <h1>Client : {{ client.name }}</h1>
        </div>
    `
})

export class ClientShow {
    client: Client;
    routeParams: RouteParams;
    repository: ClientRepository;
    constructor(repository: ClientRepository, routeParams: RouteParams) {
        this.repository = repository;
        this.routeParams = routeParams;
    }
    onActivate() {
        return this.repository.find(this.routeParams.params['id']).then(client => {
            this.client = client;
        });
    }
}

@youknowriad
Copy link
Author

@brandonroberts yes I did that, but I think angular should handle this no ? What is the purpose of waiting a promise resolution in the onActivate hook in this case ?

@brandonroberts
Copy link
Contributor

It's mainly to resolve any data or properties you may need before continuing with any child components like your doing with the client. It's not to prevent the instantiation of the component until onActivate finishes. It also provides you with information as to which component you were navigated from and the current navigation.

@btford
Copy link
Contributor

btford commented Oct 30, 2015

@brandonroberts is correct. 👍

I think for cases like yours, it's better to use the strategy @brandonroberts is suggesting with ng-if.

@youknowriad
Copy link
Author

@btford ok I'll stick with that until something like this #4015

Thank you

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants