Amrmsmb
Amrmsmb

Reputation: 1

Argument of type 'Event' is not assignable to parameter of type 'string'

in the below code I want to use the EventEmitter to result in calling the method onlyNewAddedItems.

I defined the EventEmitter instance and the method that emits the event as shown below:

@Output() newItemValue = new EventEmitter<string>();

  addNewItem(val : string) {
    this.newItemValue.emit(val);
    console.log("add new item:" + val);
    this.items.push(val);
  }

To bind to third event I did the following:

<h1 (newItemValue) = onlyNewlyAddedItems($event)></h1>

but when I compile the code, I receive the following error

Error: src/app/app.component.html:4:42 - error TS2345: Argument of type 'Event' is not assignable to parameter of type 'string'.

4 <h1 (newItemValue) = onlyNewlyAddedItems($event)></h1>                                        
  src/app/app.component.ts:5:16
    5   templateUrl: './app.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component AppComponent.
    

Please, let me know how to execute the method onlyNewlyAddedItems via EventEmitter.

AppComponent.component.ts:

import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'InputOutputBindings';
  currentItem = 'TV';
  items = ['item1', 'item2', 'item3', 'item4'];

  @Output() newItemValue = new EventEmitter<string>();

  addNewItem(val : string) {
    this.newItemValue.emit(val);
    console.log("add new item:" + val);
    this.items.push(val);
  }

  onlyNewlyAddedItems(val : string) {
    console.log("onlyNewlyAddedItems:" + val);
  }
}

app.component.html:

<h1 #test = customdirective appItemDetails [item]="currentItem">{{currentItem}}  item</h1>
<label>Add an item: <input #newItem></label>
<button (click) = addNewItem(newItem.value)>add new item</button>
<h1 (newItemValue) = onlyNewlyAddedItems($event)></h1>

Upvotes: 30

Views: 99096

Answers (12)

Aileron79
Aileron79

Reputation: 897

As mentioned in the answers before, this error often boils down to a typo or something similar you have missed. For all of you who stumble across that error (that in my opinion should be handled better by the compiler by providing a more meaningful error message), here is other things that caused that error in my projects:

  • Make sure the includes in your component are actually valid. Like templateUrl and styleUrls

  • Double check that you have added the component that provides the output parameters to the @NgModule declarations section in your module. The correct module, that is. Angular will complain about it emitting an Event datatype because it does not know about your component.

  • Make sure you have spelled the component selector correctly - in your component, and when using it in the parent. I have experienced this error message when using a component selector that does not exist at all. Believe me, it cost me hours to figure that out. A classic: Forgetting the app- prefix when using the component.

Hope it helps someone.

Upvotes: 1

Payal_kul
Payal_kul

Reputation: 1

I have omitted this error by adding the following code in app.module.ts file

import { FormsModule } from '@angular/forms';

[...]

@NgModule({
  imports: [
    [...]
    FormsModule
  ],
  [...]
})

For more information Can't bind to 'ngModel' since it isn't a known property of 'input'

Upvotes: 0

Mo D Genesis
Mo D Genesis

Reputation: 6149

I simply used a wrong variable name.

Example: Your component.ts

@Output() newItemValue = new EventEmitter<string>();

then use a wrong name:

<app-my-component (WrongName)="onNewItemValue($event)" ></app-my-component> 
// 'WrongName' Parameter needs to change to newItemValue 

Upvotes: 14

Scott-MEARN-Developer
Scott-MEARN-Developer

Reputation: 392

As other answers have already pointed out, the most likely cause is an error in your declarations/exports/imports in your module, so check that first. However, if you can't seem to fix the issues, here's a handy work around (that doesn't use 'any', which you should try to avoid using).

Step 1 - emit your data as an event in your child ts component:

@Output() newItemValue = new EventEmitter<Event>();

//...

this.newItemValue.emit(result as unknown as Event);

Step 2 - Your parent html component is the same as what you already have:

<h1 (newItemValue) = onlyNewlyAddedItems($event)></h1>

Step 3 - your parent ts component will convert the payload into the necessary data type:

  onlyNewlyAddedItems(event: Event) {
    const val = event as unknown as string;
    console.log(`onlyNewlyAddedItems:  ${val}`);
  }

Hope this helps!

Upvotes: 1

Musa Kazim
Musa Kazim

Reputation: 25

you're in strict mode, just wrap the $event in $any. it'll solve the issue

Upvotes: -1

Boris
Boris

Reputation: 471

Try

@Output("addNewItem") newItemValue = new EventEmitter<string>();

that solved a similar problem for me.

Upvotes: -1

Peter Nixey
Peter Nixey

Reputation: 16565

You're trying to handle the emitted event in the same component that you emit it from. If I remove everything else from your AppComponent it looks like this:

export class AppComponent {

  @Output() newItemValue = new EventEmitter<string>();

  # Trigger event to be emitted
  addNewItem(val : string) {
    this.newItemValue.emit(val);
  }

  # Attempt to handle event (in the same component?)
  onlyNewlyAddedItems(val : string) {
    console.log("onlyNewlyAddedItems:" + val);
  }
}
<!-- You're emitting the event here -->
<button (click) = addNewItem(newItem.value)>add item</button>

<!-- and trying to capture the event here, 
     in the same component. This won't work -->
<h1 (newItemValue) = onlyNewlyAddedItems($event)></h1>

Your event emitter and handler are both in the same component which I imagine is not what you want. An event is a way of communicating data to parent components.

Your event will be emitted from the AppComponent itself

Your event will not be emitted within the component. It will be emitted on the component, i.e. you would capture it from the app component itself:

<app-component(newItemValue)="onNewItem($event)"></app-component>

Why you're seeing the wrong event type: Event

You can add any made up event handler to any html element and Angular will just assume it's there and cast it to Event. So you think that your typing is wrong but what's acutally happened is that you've added an event handler for an event that may not (probably doesn't) exist.

Upvotes: -1

Fayyaz
Fayyaz

Reputation: 297

Temporary solution if you want to leave strict template type checking enabled is to wrap $event in $any(). Example:

$any($event)

it should work .. tested on Angular 13x

Upvotes: 28

Yukesh.M
Yukesh.M

Reputation: 27

onlyNewlyAddedItems(val: string) {
console.log("onlyNewlyAddedItems:" + val);
}

Change the method parameter datatype from string to any as below. This method works for me.

onlyNewlyAddedItems(val : any) {
console.log("onlyNewlyAddedItems:" + val);
}

Upvotes: -1

Oshan Sisa Upreti
Oshan Sisa Upreti

Reputation: 69

Check your app.module.ts file and make sure you have the components listed in your container in the declarations.

@NgModule({
   declarations : [
   AppComponent, 
   //your child component
],
...})

Upvotes: 6

iwontcode
iwontcode

Reputation: 74

Check out this StackBlitz demo. Event emitters are meant for passing data to parent component. In the example, you can see that your code works when you are emitting value from a separate child component.

Upvotes: 1

To clear the error,

In the onlyNewlyAddedItems method, you are expecting string but you're passing $event from the template. Please try with the below code.

<h1 #test = customdirective appItemDetails [item]="currentItem">{{currentItem}}  item</h1>
<label>Add an item: <input #newItem></label>
<button (click) = addNewItem(newItem.value)>add new item</button>
<h1 (newItemValue) = onlyNewlyAddedItems(newItem.value)></h1>

But listening inside the component will not work. since these decorators (Input and Output) are used to communicate outside from the component.

Upvotes: 1

Related Questions