105

I have an app where I have an upload component where I can upload a file. It is embedded in the body.component.

On upload, it should use a function (e.g. BodyComponent.thefunction()) of the parent component (do a call to update the data): but only if it the parent is specifically the body.component. The upload might also be used elsewhere with different behavior.

Something like parent(this).thefunction(), how to do that?

5 Answers 5

179

I would create a custom event in the child component. Something like this:

@Component({
  selector: 'child-comp',
  (...)
})
export class ChildComponent {
  @Output()
  uploaded = new EventEmitter<string>();

  uploadComplete() {
    this.uploaded.emit('complete');
  }

Your parent component could register on this event

@Component({
  template `
    <child-comp (uploaded)="someMethod($event)"></child-comp>
  `,
  directives: [ ChildComponent ]
})
export class ParentComponent {
  (...)

  someMethod(event) {
  }
}

Another way would be to inject the parent component in the child one, but they will be strongly linked together...

Sign up to request clarification or add additional context in comments.

12 Comments

Any idea why I have an Output undefined error? It's defined in typescript at the top by importing from angular2/core. Console log shows a problem with angular2-polyfills
Oh there is a typo in my answer: @Ouput instead of @Output. It could be the problem... I updated my answer.
Heh, didn't notice. That was it.
Now getting an uploadComplete is not defined Note that I just copied these as examples. The parent has "someMethod" as well, but it already has an issue with uploadComplete. The parent component does use the (uploaded) binding on the child node, and it already had the child as a directive.
directives and pipes inside @Component is deprecated from angular RC6.
|
66

Below is the code that worked for me in the latest

Angular 5+

class ChildComponent {
  @Output() myEvent = new EventEmitter<string>();

  callParent() {
    this.myEvent.emit('eventDesc');
  }
}

In ParentTemplate's template

<child-component (myEvent)="anyParentMethod($event)"

3 Comments

This is a good solution, because its simple, and the parent decides which method to call. Me like :-)
What if I m using router-outlet? Can i still use (myEvent)?
Its for child component used inside parent component. Not sure About router-outlet. May be this question helps you. stackoverflow.com/questions/45949476/…
41

Solution without events involved.

Suppose that I have a ChildComponent and from that I want to call the method myMethod() which belongs to ParentComponent (keeping the original parent's context).

Parent Component class:

@Component({ ... })
export class ParentComponent {

    get myMethodFunc() {
        return this.myMethod.bind(this);
    }

    myMethod() {
         ...
    }
}

Parent template:

<app-child [myMethod]="myMethodFunc"></app-child>

Child template

@Component({ ... })
export class ChildComponent {

    @Input() myMethod: Function;

    // here I can use this.myMethod() and it will call ParentComponent's myMethod()
}

5 Comments

I've tried using this but it does not work for me. In my version of myMethod, it references a tabset on the parent component (I'm trying to switch tabs from a child of the parent). When I reference this in the parent, everything works. From the child it's getting into myMethod, but not changing the tab. So I'm wondering if the tabset it is referencing is a copy of the real one when the child is accessing it. I'm not actually sure what's happening here when this.myMethod.bind(this) is being returned. (Possibly I'm instead doing something fundamentally wrong.)
I know but I am not using the 8th version. I need this for Ionic 3 that uses the 5 version.
@VasilisGreece I'm not sure how to help you, but I strongly suggest you to update to latest Ionic version (currently 4)
Simplest and most direct way to call the parent's method avoiding unnecessary imports. Using Angular 10 on 2020-11-13. Appreciated.
This works on 1-27-2022, I tried a lot of other methods including Output() but they all failed but this worked! Thank you, you're brilliant.
24

You can inject the parent component to the child component.

For more details see
- How do I inject a parent component into a child component?
- Angular 2 child component refers to parent component This way you can ensure that thefunction() is only called when parent is a body.component.

constructor(@Host() bodyComp: BodyComponent) {

Otherwise using @Output() is preferred to communicate from child to parent.

2 Comments

Btw, I had to do constructor(@Host() bodyComp: BodyComponent).. perhaps it was changed recently. Works great, thx!
Thanjs a lot, I mixed something up - fixed
3

In parent html:

<child [parent]="this"></child>

In child component:

@Input() parent: ParentComponent;
// then do whatever with `this.parent`

Events have their places, but I don't see anything else is simpler than this.

1 Comment

For Angular 13, this is the only answer that works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.