I have an object L2Language
with three properties: short
, long
, and videos
. It works as expected in the child component and now I'm trying to pass the object from the child component to the parent component via an event emitter:
(L2LanguageEvent)="L2LanguageEventHandler($event)"
The object is passing to the parent. When I view the object in the console with console.table(L2LanguageEvent);
the properties are there:
but when I log a property on the object with console.log(L2LanguageEvent.short);
I'm told that the property isn't on the object:
Property 'short' does not exist on type 'object'.
Here's my parent component:
import { Component, OnInit } from '@angular/core';
import { L2Language } from './home-toolbar/home-toolbar.component';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
language: L2Language;
ngOnInit(): void {
console.log(this.language); // doesn't work
}
L2LanguageEventHandler(L2LanguageEvent: object) {
console.table(L2LanguageEvent); // works, you see the result above
console.log(L2LanguageEvent.short); // doesn't work
console.log(L2LanguageEvent['short']); // doesn't work
this.language = L2LanguageEvent; // doesn't work
}
}
console.log(this.language);
returns undefined
. This suggests that the interface L2Language
was never imported. I'm not getting the error Cannot find module
so it's not a path problem. Or maybe it's saying the L2Language
was imported but the property values are undefined? This is true but it shouldn't cause the error saying that the property doesn't exist on the object.
console.log(L2LanguageEvent.short);
returns the error Property 'short' does not exist on type 'object'.
console.log(L2LanguageEvent['short']);
returns two errors:
Element implicitly has an 'any' type because expression of type '"short"' can't be used to index type '{}'.
Property 'short' does not exist on type '{}'.
this.language = L2LanguageEvent;
returns the error
Type '{}' is missing the following properties from type 'L2Language': short, long, videos
Thanks for your help.
CodePudding user response:
The problem is with this part of the code
L2LanguageEventHandler(L2LanguageEvent: object) { //CHANGE THIS object
console.table(L2LanguageEvent); // works, you see the result above
console.log(L2LanguageEvent.short); // doesn't work
console.log(L2LanguageEvent['short']); // doesn't work
this.language = L2LanguageEvent; // doesn't work
}
Instead of object just use your interface.
L2LanguageEventHandler(L2LanguageEvent: L2Language){}
CodePudding user response:
I'd made two mistakes. First, in the child component I'd written:
export interface L2Language = {
short: string;
long: string;
videos: string;
};
export class HomeToolbarComponent implements OnInit {
@Output() L2LanguageEvent = new EventEmitter<object>();
}
This is correct:
export interface L2Language = {
short: string;
long: string;
videos: string;
};
export class HomeToolbarComponent implements OnInit {
@Output() L2LanguageEvent = new EventEmitter<L2Language>();
Second, in the parent component this was incorrect:
L2LanguageEventHandler(L2LanguageEvent: object) {
console.table(L2LanguageEvent);
console.log(L2LanguageEvent.short);
}
This is correct:
L2LanguageEventHandler(L2LanguageEvent: L2Language) {
console.table(L2LanguageEvent);
console.log(L2LanguageEvent.short);
}
Rereading the TypeScript Handbook, I see that object
isn't a type. You make an object, give it a name, and then the type is the name. In fact, I can make my object a type
instead of an interface
:
export type L2Language = {
short: string;
long: string;
videos: string;
};
Note that there's an =
in there now! The TypeScript Handbook explains that
the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
You don't have to name an object, you can make in anonymous. That might be good for an object that it used in one function but for an object that's passed between components it should be a named type
or interface
.
Thanks Daniel!