Angular 2 - Ng To use numbers instead of collections
... eg...
<div class="month" *ngFor="#item of myCollection; #i = index"> ... </div> You can do something like ...
<div class="month" *ngFor="#item of 10; #i = index"> ... </div> ... without involving a non-standard solution, for example:
<div class="month" *ngFor="#item of ['dummy','dummy','dummy','dummy','dummy', 'dummy','dummy','dummy']; #i = index"> ... </div> ?
Inside your component, you can define an array of numbers (ES6), as described below:
export class SampleComponent { constructor() { this.numbers = Array(5).fill().map((x,i)=>i); // [0,1,2,3,4] this.numbers = Array(5).fill(4); // [4,4,4,4,4] } } See this link to create an array: Tersest is a way to create an array of integers from 1..20 in JavaScript .
Then you can ngFor over this array with ngFor :
@Component({ template: ` <ul> <li *ngFor="let number of numbers">{{number}}</li> </ul> ` }) export class SampleComponent { (...) } Or briefly:
@Component({ template: ` <ul> <li *ngFor="let number of [0,1,2,3,4]">{{number}}</li> </ul> ` }) export class SampleComponent { (...) } No, there is no way for NgFor to use numbers instead of collections. At the moment * ngFor only accepts a collection as a parameter, but you can do it in the following ways:
Using pipes
pipe.ts
import {Pipe, PipeTransform} from 'angular2/core'; @Pipe({name: 'demoNumber'}) export class DemoNumber implements PipeTransform { transform(value, args:string[]) : any { let res = []; for (let i = 0; i < value; i++) { res.push(i); } return res; } } <ul> <li>Method First Using PIPE</li> <li *ngFor='let key of 5 | demoNumber'> {{key}} </li> </ul> Using an array of numbers directly in HTML (view)
<ul> <li>Method Second</li> <li *ngFor='let key of [1,2]'> {{key}} </li> </ul> Using the Split Method
<ul> <li>Method Third</li> <li *ngFor='let loop2 of "0123".split("")'>{{loop2}}</li> </ul> Using create a new array in a component
<ul> <li>Method Fourth</li> <li *ngFor='let loop3 of counter(5) ;let i= index'>{{i}}</li> </ul> export class AppComponent { demoNumber = 5 ; counter = Array; numberReturn(length){ return new Array(length); } } Working demo
@OP, you were very close with your "not elegant" solution.
What about:
<div class="month" *ngFor="let item of [].constructor(10); let = index">... </div>
Here I get the Array constructor from an empty array: [].constructor , because Array not a recognized character in the template syntax, and I'm too lazy to do Array=Array or counter = Array in the [].constructor component as @ pardeep-jain did in 4th example. And I call it without new because new not needed to get an array from the Array constructor.
Array(30) and new Array(30) equivalent.
The array will be empty, but that doesn't matter, because you really want to use i from ;let = index in your loop.
I could not bear the idea of allocating an array for simple repetition of components, so I wrote a structural directive. In its simplest form, this does not make the index available to the template; it looks like this:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[biRepeat]' }) export class RepeatDirective { constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { } @Input('biRepeat') set count(c:number) { this.viewContainer.clear(); for(var i=0;i<c;i++) { this.viewContainer.createEmbeddedView(this.templateRef); } } } I solved this using Angular 5.2.6 and TypeScript 2.6.2:
class Range implements Iterable<number> { constructor( public readonly low: number, public readonly high: number, public readonly step: number = 1 ) { } *[Symbol.iterator]() { for (let x = this.low; x <= this.high; x += this.step) { yield x; } } } function range(low: number, high: number) { return new Range(low, high); } This can be used in a component like this:
@Component({ template: '<div *ngFor="let i of r">{{ i }}</div>' }) class RangeTestComponent { public r = range(10, 20); } Errors and statements are specifically omitted for brevity (for example, what happens if the step is negative).
You can use lodash:
@Component({ selector: 'board', template: ` <div *ngFor="let i of range"> {{i}} </div> `, styleUrls: ['./board.component.css'] }) export class AppComponent implements OnInit { range = _.range(8); } I have not tested the code, but it should work.
You can also use this.
export class SampleComponent { numbers:Array<any> = []; constructor() { this.numbers = Array.from({length:10},(v,k)=>k+1); } } HTML
<p *ngFor="let i of numbers"> {{i}} </p> Since the fill () method (mentioned in the accepted answer) throws an error without arguments, I would suggest something like this (works for me, Angular 7.0.4, Typescript 3.1.6)
<div class="month" *ngFor="let item of items"> ... </div> In component code:
this.items = Array.from({length: 10}, (v, k) => k + 1); If you want to increase the size of the array dynamically after clicking on the button, find my attached dynamic solution (this is how I got to this question).
Highlighting the necessary variables:
array = [1]; arraySize: number; Declare a function that adds an element to the array:
increaseArrayElement() { this.arraySize = this.array[this.array.length - 1 ]; this.arraySize += 1; this.array.push(this.arraySize); console.log(this.arraySize); } Call function in html
<button md-button (click)="increaseArrayElement()" > Add element to array </button> Iterating through an array using ngFor:
<div *ngFor="let i of array" > iterateThroughArray: {{ i }} </div> The easiest way I've tried
You can also create an array in your component file and call it using the * ngFor directive, returning as an array.
Something like that....
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-morning', templateUrl: './morning.component.html', styleUrls: ['./morning.component.css'] }) export class MorningComponent implements OnInit { arr = []; i: number = 0; arra() { for (this.i = 0; this.i < 20; this.i++) { this.arr[this.i]=this.i; } return this.arr; } constructor() { } ngOnInit() { } } And this function can be used in your HTML template file.
<p *ngFor="let a of arra(); let i= index"> value:{{a}} position:{{i}} </p> My decision:
export class DashboardManagementComponent implements OnInit { _cols = 5; _rows = 10; constructor() { } ngOnInit() { } get cols() { return Array(this._cols).fill(null).map((el, index) => index); } get rows() { return Array(this._rows).fill(null).map((el, index) => index); } In HTML:
<div class="charts-setup"> <div class="col" *ngFor="let col of cols; let colIdx = index"> <div class="row" *ngFor="let row of rows; let rowIdx = index"> Col: {{colIdx}}, row: {{rowIdx}} </div> </div> </div> This can also be achieved as follows:
HTML:
<div *ngFor="let item of fakeArray(10)"> ... </div> Typescript:
fakeArray(length: number): Array<any> { if (length >= 0) { return new Array(length); } }