147

I have in my component an EventEmitter but I can't compile it because it throws the error:

Supplied parameters do not match any signature of call target

My component:

@Output() addModel = new EventEmitter<any>();

saveModel($event, make, name) {
  this.addModel.emit(make, name);
}

If I delete one of the parameters in this.addModel.emit() it works but is it possible to pass 2 parameters to EventEmitter and how?

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
LorenzoBerti
  • 6,704
  • 8
  • 47
  • 89

4 Answers4

267

If you look at the EventEmitter emit method @ angular.io, it can only take a single parameter of type T

emit(value?: T)

Since only a single parameter is allowed, consider passing it as an object in emit method.

In the snippet below, make & name variables are holding their respective values:

this.addModel.emit({make: make, name: name});
//shorthand is below
this.addModel.emit({make, name});
BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • 2
    Oh, ok, Thankyou! it will this.addModel.emit({make:make, name:name}); – LorenzoBerti Dec 06 '16 at 19:52
  • 4
    @echonax no need to do that, es6 will take care of it [check here](http://www.benmvp.com/learning-es6-enhanced-object-literals/) – Pankaj Parkar Dec 06 '16 at 19:56
  • how can i observe/ take this value in parent component? – roshini May 24 '17 at 07:27
  • @roshini please take a look at how [component interaction](https://angular.io/docs/ts/latest/cookbook/component-communication.html) happens, basically you need to emit data from child component to parent component using `EventEmitter` object.. – Pankaj Parkar May 24 '17 at 07:58
  • thanks for your response, i know this emitter between components but need interaction as passing data from directive to component.. – roshini May 25 '17 at 06:47
  • please give better example? what is make and name? – user1034912 Jan 14 '18 at 18:49
  • @user1034912 may I know reason behind the answer? This answer is explanation based on whatever OP have been asked. If you don't understand. consider open a new question. Though I updated my answer, so that you could understand ES6 shorthand syntax. Let me know if you need further help. – Pankaj Parkar Jan 15 '18 at 05:56
  • Or else you can pass it as an array this.addModel.emit( [make, name] ) – Lalana Chamika Feb 23 '21 at 09:26
  • @PankajParkar I like the idea of strongly typing the object, but is there a way to make the input function receive a strongly typed object instead of an 'any' type? specifically just two strings in my case. – S. Cannon Jul 22 '22 at 15:39
  • @S.Cannon can you please elaborate more? – Pankaj Parkar Jul 22 '22 at 15:44
84

Another option to strongly type it is as follows:

@Output addModel = new EventEmitter<{make: string, name: string}>();

you can then emit it like @Pankaj-Parkar shows

this.addModel.emit({make, name});
or
this.addModel.emit({make: 'honda', name: 'civic'});

You now have strong typing instead of using object or any.

Andy Danger Gagne
  • 2,107
  • 1
  • 17
  • 26
  • This is the correct and complete solution, because it keeps the type of the arguments all the way through to the listener, which can also be strongly typed. – GK100 Mar 12 '22 at 02:29
  • is there a way to make the input strongly typed too on the receiving component? I'd ideally want the function that takes the emitted event to force a object of two strings to be received, rather than a type 'any'. How would you do that? – S. Cannon Jul 22 '22 at 15:43
  • 1
    @S.Cannon, I'm fairly new to Angular/TypeScript but I just tried this syntax as a function argument type (like `foo(event: {make: string, name: string})`) and it worked perfectly. – Gustavo Silva Sep 07 '22 at 18:32
25

I fixed it by making

EventEmitter<object>();

Then I was able to pass an object such as:

this.MyOutputVariable.emit({ name: 'jack', age: '12' });

And it worked.

Kos
  • 4,890
  • 9
  • 38
  • 42
Adham Amiin
  • 809
  • 7
  • 5
  • 1
    This is great, Adham. Nothing against your answer, but it is worth noting that a standard practice -- and a good practice -- is to always supply an *Event Object in tandem with 1 or more values*: `publish(event, value)` & `subscribe(e, value) {...}`. I'm a little surprised that Angular defined their interface / implemented this the way they did. – Cody Mar 05 '18 at 21:53
  • 6
    Downvoted in favor of strongly types solutions like `new EventEmitter<{name: string, age: number}>();` – Liero Jul 16 '19 at 07:09
9

I know this is an old Question for me I would create an interface and send it as an object where I can have my code more organized

 export interface addModelArgs{
      make:string,
      name:string
    }
@Output() addModel = new EventEmitter<addModelArgs>();

and call it as following

    this.addModel.emit({make: 'honda', name: 'civic'});
or 
    let savParamters:addModelArgs={make: 'honda', name: 'civic'};

    this.addModel.emit(savParamters);
khaled Dehia
  • 821
  • 7
  • 13