Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can my child component call a method on the parent component in Angular 2?

Background

Suppose I have some parent component, call it MatchList, that presents a list of Hero objects, among other things. Each Hero object has properties that are shown in some table. Now suppose I also have a button for each Hero that updates the route, loads a new view, and shows more details.

Before

http://heroic.com/match-list

After

http://heroic.com/hero-84

Problem

My problem essential is this: I want to call the router's navigate() method from a button in my MatchList template, but I receive the following error when I attempt to do so:

EXCEPTION: Error during evaluation of "click"BrowserDomAdapter.logError @ ... angular2.dev.js:21835 ORIGINAL EXCEPTION: TypeError: l_context.setPath is not a function... angular2.dev.js:21835 TypeError: l_context.setPath is not a function at ...

In other words It looks like I cannot reference the parent component's router methods in the child template.

So, what is the correct and best way in Angular 2 for a child component access the methods of the parent component ( or 'context')?

I'd prefer if the solution was something cleaner than

class parent {

     child: Child;

     constructor(...) {

        ...

        this.child.parent = this;

     }
}

Sample Code

EDIT I changed my template button to

(^click)="setPath(match.match_id)"

I am not longer receiving an error message, but nothing happens - I don't even get a console log confirming the click.


Snippets of what I have so far.

//Parent

    @Component({
        selector: 'dota-app',
        directives: [Home, MatchesView, ROUTER_DIRECTIVES],
        templateUrl: 'AppView.html'
    })
    @RouteConfig([
        { path: '/', component: Home, as: 'Home' },
        { path: '/matches', component: MatchesView, as: 'Matches' },
        { path: '/match-details', component: MatchDetailsView, as: 'MatchDetails'}
    ])
    export class RootDotaComponent {

        router: Router;

        constructor(router: Router) {

            this.router = router;

        }

        public setPath(linkParams: any[]|string): void {

            if (typeof linkParams === "string")
                linkParams = [linkParams];

            this.router.navigate(<any[]>linkParams);

        }

    }

}

//Child

@Component({
    selector: 'matches-view',
    providers: [DotaRestDao],
})
@View({
    templateUrl: './components/MatchesView/MatchesView.html',
    directives: [CORE_DIRECTIVES]
})
export class MatchesView {

    public result;

    private dataService: DotaRestDao;

    constructor(dataService: DotaRestDao) {

        this.result = { matches: [] };

        this.dataService = dataService;

        this.dataService.getData({
            baseUrl: DotaRestDao.MATCH_HISTORY_BASE
        }).subscribe(
            res => this.result = res.result,
            err => console.log("something wrongable", err),
            () => console.log('completed')
        );

    }

}

//Template

<table class="table">
              ...
    <button (click)="setPath(match.match_id)">Match Detail Route</button>
</table>
like image 762
Jefftopia Avatar asked Nov 12 '15 04:11

Jefftopia


People also ask

How do you call a method in parent component from a child component?

Call Parent Component method from Child Component For Calling Parent Component method from Child Component, I had created a method getParentMethod and in this method, I had set input property in HTML file of parent component. Then shown as below code inside the child component I am able to access parent method.

How does a child component communicate with a parent component in angular?

The <parent-component> serves as the context for the <child-component> . @Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.


1 Answers

In the context of this question, namely calling a parent router, the answer, it turns out, is trivial. See this plunker for details.

The main takeaway is that giving a router to a child component a la

class ChildComponent {

    constructor(router: Router) {

        ...

    }

}

does not create a new router, it merely extends the existing router of the parent component. Thus, the need to a reference to the parent object is obviated. Just call the methods of the childRouter and everything works as expected.

like image 183
Jefftopia Avatar answered Sep 27 '22 21:09

Jefftopia