37

I'm building a project using Angular, I started the project using angular-cli and when I try to run ng build --prod i keep getting this error:

Property 'description' does not exist on type Object

The code generating this error is the following:

export class AppComponent {
    product: Object = {};

    constructor(
        private store: StoreService,
        private request: RequestService,
    ) {
        this.product = this.request.getProduct(_id);
    }
}

<p>{{product.description}}</p>

I was reading some content about this and the error is because I'm using type definition to define product as Object, but I'm not passing any property definition.

I know I could define an Interface, like I do with arrays, but I wasn't able to do it. I don't know if I'm defining it wrong, this is how I tried:

export interface ProductInterface {
    id: Number;
    description: String;
    title: String;
}

product: Object<ProductInterface> = {};

But it also gives me errors. What do I need to do to avoid this?

celsomtrindade
  • 4,501
  • 18
  • 61
  • 116

8 Answers8

31

For your first example. In your html, you are saying product has the property description (which it does not on type Object)

In your second example. You are initially defining product as an empty object

product: ProductInterface = {};

Which is missing the required fields of the interface. So you can remove the initialization, leaving

product: ProductInterface;

Also as others have noted, you do not need the Object<> syntax

LLai
  • 13,128
  • 3
  • 41
  • 45
  • 1
    I have a dynamic form and don't know any form control while compilation, at compilation time I get for ex:`Property 'name' does not exist on type '{}'.` any solutions for this type of forms? – Nikhil Radadiya Nov 15 '17 at 10:57
  • 2
    @NikhilRadadiya If there are unknown properties in your object you can add dynamic properties `product: {[key: string]: string}` This will allow you to assign whatever key (type string) to the object with a value (type string). This is called an index signature (https://basarat.gitbooks.io/typescript/docs/types/index-signatures.html) – LLai Nov 15 '17 at 14:28
  • 1
    Thank you very much man, you saved many lives, that index structure is working like a charm – Nikhil Radadiya Nov 17 '17 at 04:45
  • @NikhilRadadiya glad I could help! – LLai Nov 17 '17 at 05:31
9

From my case..

ngOnInit(){
    this.product = this.request.getProduct(_id); // who is _id
} 

Just adding data:any at subscription works fine.

this.request.getProduct(_id).subscribe((data: any) => {
   this.product=data;
});

This would helpful while the response data having more key, value pairs. (So Its hard/Time consuming to create Interface.)

But always the best practise is to use Interfaces ;)

Silambarasan R
  • 1,346
  • 15
  • 22
8

If the property is dynamic (not known at compile time), you can use

someObject['someProperty']

instead of

someObject.someProperty
5

First of all I would simply use product: ProductInterface; and you don't even have to initialize it.

Then, probably this will fix your error {{ product?. description }}

crash
  • 4,152
  • 6
  • 33
  • 54
  • What does it mean to use `?` ? – celsomtrindade Jun 28 '17 at 20:45
  • @celsomtrindade that is the safe navigation operator (I believe its called elvis operator in other languages) http://www.concretepage.com/angular-2/angular-2-pipe-operator-and-safe-navigation-operator-example . Basically angular won't look for the description field until product is defined. Without it you may get an cannot read property description of undefined error. – LLai Jun 28 '17 at 21:12
0

You must define the request in OnInit method, your controller that implements OnInit interface and define a new method

ngOnInit(){
    this.product = this.request.getProduct(_id); // who is _id
} 

Assuming that getProduct() is http request that return a observable

this.request.getProduct(_id).subscribe((data) => {
   this.product=data;
});
alehn96
  • 1,363
  • 1
  • 13
  • 23
0

It is safe to use any rather than Object when data is requested from server, because we don't know what will be returned from server. So you don't need to typecheck ie:

export class AppComponent {
    product: any;

    constructor(
        private store: StoreService,
        private request: RequestService,
    ) {
        this.product = this.request.getProduct(_id);
    }
}
suhailvs
  • 20,182
  • 14
  • 100
  • 98
  • While this may be true at the time it was written, TypeScript has since included `unknown` to serve this very purpose – Max Coplan Jan 14 '21 at 21:02
0

If you use command ng serve and build success.

May,you have the trouble with build configuration

maybe you need to modify the className.prod.ts like className.ts

my another answer has more detail:

Angular - How to fix 'property does not exist on type' error?

我零0七
  • 315
  • 3
  • 6
-2

In my case it worked after set my properties as public

So, just change this

export interface ProductInterface {
    id: Number;
    description: String;
    title: String;
}

to this

export interface ProductInterface {
    public id: Number;
    public description: String;
    public title: String;
}
Jorge Casariego
  • 21,948
  • 6
  • 90
  • 97