Can ngForIn be used in angular 4?

Viewed 4577

I am trying to iterate over the properties of an object using *ngFor but using in. When I try to do this

@Controller({
  selector: 'sample-controller',
  template: `
    <ul>
      <li *ngFor="let i in obj">
        <b>{{i}}</b>: {{obj[i]}}
      </li>
    </ul>`
})
class SampleController {
  obj = {a: 1, b: 2}
}

I get the error message:

Can't bind to 'ngForIn' since it isn't a known property of 'li'.

I have included FormsModule and BrowserModule in the imports section of the @NgModule for this component.

Is it possible to use ngForIn on li and if not is there an idiomatic alternative?

4 Answers

Things have changed a bit (at Angular 9) so the answer by yurzi wont work but on the similar lines setting your 'forOf' value into 'super.ngForOf' will do the trick

import {   ContentChildren,   Directive,   Input,   IterableDiffers,   NgIterable,   OnChanges,   SimpleChanges,   TemplateRef,   ViewChildren,   ViewContainerRef } from "@angular/core";

import { NgForOf } from "@angular/common";

export interface Selectable<T> {   selected: boolean;   isActive: boolean; }

@Directive({   
 selector: "[optionsFor][[optionsForOf]]" }) 
 export class OptionsForDirective<T extends Selectable<any>,U extends NgIterable<T> = NgIterable<T>> 
     extends NgForOf<T, U> implements OnChanges {   

   _editMode = false;   
   _forOf: Array<Selectable<any>>;

  @Input()   
  set iefOptionsForOf(value: any) {
    this._forOf = value;
    console.log("set of: ", value);   
  }

  @Input()   
  set iefOptionsForEditMode(value: boolean) {
    this._editMode = value;
    console.log("set edit mode: ", value);   
  }

  constructor(
    public _viewContainer2: ViewContainerRef,
    public _templateRef2: TemplateRef<any>,
    public _differs2: IterableDiffers   ) {
    super(_viewContainer2, _templateRef2, _differs2);   
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes.optionsForOf) {
      const origNgForOf: Array<Selectable<any>> = this._forOf;
      let filtered = origNgForOf;
      if (origNgForOf) {
        filtered = origNgForOf.filter(s => {
          return this._editMode || s.isActive !== false;
        });
      }
      console.log("filtered", filtered);

      super.ngForOf = filtered as any;
    }   
  } 
}

Object.keys and Object.values can be assigned to public properties on the component and then they are available as functions in a template. eg

//somewhere in the component
public objectKeys = Object.keys;
public objectValues = Object.values;

//somewhere in template
...*ngFor="let key of objectKeys(someObject)"...
Related