482

What am I doing wrong?

import {bootstrap, Component} from 'angular2/angular2'

@Component({
  selector: 'conf-talks',
  template: `<div *ngFor="let talk in talks">
     {{talk.title}} by {{talk.speaker}}
     <p>{{talk.description}}
   </div>`
})
class ConfTalks {
  talks = [ {title: 't1', speaker: 'Brian', description: 'talk 1'},
            {title: 't2', speaker: 'Julie', description: 'talk 2'}];
}
@Component({
  selector: 'my-app',
  directives: [ConfTalks],
  template: '<conf-talks></conf-talks>'
})
class App {}
bootstrap(App, [])

The error is

EXCEPTION: Template parse errors:
Can't bind to 'ngForIn' since it isn't a known native property
("<div [ERROR ->]*ngFor="let talk in talks">
Lazar Ljubenović
  • 18,976
  • 10
  • 56
  • 91
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492

12 Answers12

950

I typed in instead of of in the ngFor expression.

Befor 2-beta.17, it should be:

<div *ngFor="#talk of talks">

As of beta.17, use the let syntax instead of #. See the UPDATE further down for more info.


Note that the ngFor syntax "desugars" into the following:

<template ngFor #talk [ngForOf]="talks">
  <div>...</div>
</template>

If we use in instead, it turns into

<template ngFor #talk [ngForIn]="talks">
  <div>...</div>
</template>

Since ngForIn isn't an attribute directive with an input property of the same name (like ngIf), Angular then tries to see if it is a (known native) property of the template element, and it isn't, hence the error.

UPDATE - as of 2-beta.17, use the let syntax instead of #. This updates to the following:

<div *ngFor="let talk of talks">

Note that the ngFor syntax "desugars" into the following:

<template ngFor let-talk [ngForOf]="talks">
  <div>...</div>
</template>

If we use in instead, it turns into

<template ngFor let-talk [ngForIn]="talks">
  <div>...</div>
</template>
starball
  • 20,030
  • 7
  • 43
  • 238
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • 7
    And yes, **remember** the `#` before the `talk` variable (as your said: "hope it helps someone else down the road... probably me!") – Aurelio Jan 13 '16 at 15:42
  • 2
    @Nobita, yes, that one has tripped me up just as often. I wrote a Q&A for that one too: http://stackoverflow.com/questions/34012291/angular2-exception-cant-bind-to-ngfor-since-it-isnt-a-known-native-property – Mark Rajcok Jan 13 '16 at 16:34
  • 2
    so stinking obvious when you realise... I find it really counter-intuitive, so used to for-in style. I would up vote both your Q&A posts more if I could, thanks – Pete Feb 04 '16 at 14:50
  • 3
    Thanks Mark. It's not the greatest error message - like WTF is "ngForIn" supposed to mean!? But in retrospect, duh! I wrestled with this for like 20 minutes before I found your Q&A. – Methodician Jun 08 '16 at 17:07
  • I don't know why the original answer was updated to be only beta 17 + syntax. I reverted the answer so that it has the pre-beta 17 syntax, with the *new* syntax noted as an update. Some of us are still on the older betas! all code updates should be additions to the question or answer, not replacements for the originals. – ps2goat Nov 23 '16 at 19:35
  • 2
    I agree that the answer should have both. But I further updated the answer to make it clearer that post beta.17 the syntax is different. (I stopped short of swapping around it so the latest is first). Instead I just put a small note in. At first glance, a newcomer may not realise the latest syntax. Its a minor change but makes a big difference – redfox05 Jan 27 '17 at 07:48
  • please take al look at angular2 forLoop documentation http://stackoverflow.com/documentation/angular2/6543/angular-2-forloop#t=201702190649585012149 – Yoav Schniederman Feb 19 '17 at 06:50
  • looks like the `ngFor let-childSuffix [ngForIn]="children"` thing doesn't work in Angular 6. Is there a way to iterate `in` object keys, not `of` array items? PS nevermind, looks like https://stackoverflow.com/a/51735083/3995261 answers my question – YakovL Aug 20 '19 at 19:47
349

TL;DR;

Use let...of instead of let...in !!


If you're new to Angular (>2.x) and possibly migrating from Angular1.x, most likely you're confusing in with of. As andreas has mentioned in the comments below for ... of iterates over values of an object while for ... in iterates over properties in an object. This is a new feature introduced in ES2015.

Simply replace:

<!-- Iterate over properties (incorrect in our case here) -->
<div *ngFor="let talk in talks">

with

<!-- Iterate over values (correct way to use here) -->
<div *ngFor="let talk of talks">

So, you must replace in with of inside ngFor directive to get the values.

Liam
  • 27,717
  • 28
  • 128
  • 190
mamsoudi
  • 3,999
  • 1
  • 15
  • 24
  • 2
    As an aside - does anyone know the reason behind the use of "of", "in" seems a more natural choice here. – Morvael Jun 22 '17 at 16:28
  • 3
    @mamsoudi @Morvael The difference is that `for..in` iterates the object's keys/properties while `for...of` iterates the object's values. `for(prop in foo) {}` is the same as `for(prop of Object.keys(foo)) {}`. This is a new language feature of ECMA Script 2015 / ES6. So this is only remotely an Angular issue. – Andreas Baumgart Aug 14 '17 at 15:38
  • 1
    this is what happens when you have been coding in C# for years and then move on to angular – SamuraiJack Apr 14 '19 at 07:16
24

There is an alternative if you want to use of and not switch to in. You can use KeyValuePipe introduced in 6.1. You can easily iterate over an object:

<div *ngFor="let item of object | keyvalue">
  {{item.key}}:{{item.value}}
</div>
Krishna
  • 6,107
  • 2
  • 40
  • 43
15

use of instead of in. You can use KeyValue Pipe . You can easily iterate over an object:

<div *ngFor="let items of allObject | keyvalue">
  {{items.key}}:{{items.value}}
</div>
Naeem Bashir
  • 1,937
  • 20
  • 17
13

Try to import import { CommonModule } from '@angular/common'; in angular final as *ngFor ,*ngIf all are present in CommonModule

Liam
  • 27,717
  • 28
  • 128
  • 190
Rohitesh
  • 1,514
  • 7
  • 28
  • 51
11

In my case, WebStrom auto-complete inserted lowercased *ngfor, even when it looks like you choose the right camel cased one (*ngFor).

Eran Shabi
  • 14,201
  • 7
  • 30
  • 51
7

My problem was, that Visual Studio somehow automatically lowercased *ngFor to *ngfor on copy&paste.

Liam
  • 27,717
  • 28
  • 128
  • 190
Tomino
  • 5,969
  • 6
  • 38
  • 50
0

Basically, if you create a popup using a new class, so at that time you have to add that class under the

declarations: []

In base.module.ts or app.module.ts

My Example code

##########################MY COMPONENT##################################

@Component({
  selector: 'app-modal-content',
  templateUrl: './order-details.html',
  encapsulation: ViewEncapsulation.None,
  styles: []
})

export class NgbdModalContent {
  @Input() orderDetails: any;
  private orderId;
  private customer;
  private orderDate;
  private shipDate;
  private totalAmount;
  private salesTax;
  private shippingCost;
  private transactionStatus;
  private isPaid;
  private isMailSent;
  private paymentDate;

  // private orderDetails;

  constructor(public activeModal: NgbActiveModal) {
  }
}

###########################BASE MODULE#################################

@NgModule({
    imports: [
        CommonModule,
        FormsModule
    ],
  declarations: [
    NavbarsComponent,
    NgbdModalContent,
  ]
})
export class BaseModule { }
Rajitha Bhanuka
  • 714
  • 10
  • 11
0

Simply changing "in" to "of" solved my same problem.

Chnage <div *ngFor="let talk in talks">

to     <div *ngFor="let talk of talks">
shyam yadav
  • 214
  • 1
  • 10
0

To add one more gotcha, I naively discovered that if you don't use a let statement to assign the index of the loop you also get the same error:

<span *ngFor="let button of buttons; i: index; trackBy: trackBy">
...
</span>

also throws the same error. The following version fixes it

<span *ngFor="let button of buttons; let i = index; trackBy: trackBy">
...
</span>
Peter Nixey
  • 16,187
  • 14
  • 79
  • 133
-6

Q:Can't bind to 'pSelectableRow' since it isn't a known property of 'tr'.

A:you need to configure the primeng tabulemodule in ngmodule

-20

my solution was - just remove '*' character from the expression ^__^

<div ngFor="let talk in talks">
Unkas
  • 3,522
  • 2
  • 19
  • 23