25
  • I don't want to use for loop to convert Object to Array like this! If doubled the process and slow down the performance of app (I'm using Ionic2 and Typescript, with Firebase)

    for(let key in data) { array.push(value); }

Is there any solution to iterate object itself(shown in picture attached) using *ngFor.

Or I can convert this Object(shown in picture attached) to Array, so that can be iterable in *ngFor.

enter image description here

Ankit Maheshwari
  • 1,620
  • 6
  • 28
  • 55

6 Answers6

60

You can use Object.keys(obj) to get named indexes. This will return an array structure which you can use/customize further. A sample use to iterate over object values may look like this

var persons = { 
    john: { age: 23, year:2010},
    jack: { age: 22, year:2011},
    jenny: { age: 21, year:2012}
}

Getting an iterator

var resultArray = Object.keys(persons).map(function(personNamedIndex){
    let person = persons[personNamedIndex];
    // do something with person
    return person;
});

// you have resultArray having iterated objects 
Farooq Ahmed Khan
  • 3,975
  • 3
  • 27
  • 36
  • 1
    I don't want to loop through! Is there any solution to loop through directly in dom? (Otherwise double loop will be executed!) – Ankit Maheshwari Jan 04 '17 at 08:17
  • well, i don't have much knowledge about Ionic, but in Angular you can user '(key, value) in persons' on iterator directives, hope it helps with your concern regarding direct manipulation of DOM avoiding a loop through. – Farooq Ahmed Khan Jan 04 '17 at 09:00
  • 1
    (key, value) does not worked in Angular2 (Typescript - ES5) OR Object of Objects can't be looped through! I tried doesn't worked ;( – Ankit Maheshwari Jan 04 '17 at 16:45
  • I created an example of how it works. Hope it helps http://codepen.io/farooqkhan/pen/mRbMZV – Farooq Ahmed Khan Jan 05 '17 at 07:25
  • Thanks Farooq. [ng-repeat="(key, value) in persons"] works well in Angular, but in Angular2 using *ngFor that [(key, value) in persons] does not worked! Where 'persons' is an Object of Objects (not Array) - as I shown in attached image of question. – Ankit Maheshwari Jan 06 '17 at 08:35
  • @AnkitMaheshwari here's my answer to explain how to do it without looping https://stackoverflow.com/a/69219985/2482582 – Moebius Sep 17 '21 at 08:31
29

Since Angular 6, there is now a keyvalue pipe operator. Simple do the following:

*ngFor="let item of objectList | keyvalue"

item.key # refers to the keys (134, 135...) in your example
item.value # refers to the object for each key
Pankaj
  • 474
  • 1
  • 3
  • 16
henry74
  • 1,015
  • 1
  • 10
  • 14
  • 2
    Perfect! This should be the accepted answer. Exactly what I was needing to figure out. Thank you! – TheTC Sep 05 '19 at 15:35
  • Also consider the programmatic version of this; 1) register KeyValuePipe in app.module 2) inject into constructor `private keyval: KeyValuePipe` 3) use it like this `let keyvalueData = this.keyval.transform(data);` – DFSFOT Jan 09 '20 at 02:17
11

If you don't need the indexes, you can use Object.values(yourObject) to get an array of the inner objects.

moez82
  • 111
  • 1
  • 2
2

The stadard library funtion Object.entries does that for you. Documentation

Here's an exemple of using Object.entries in a function to convert an object of (key -> object of type A) to a list of object of type A with the property name and the key as the value of that name property:

function f<A>(input: { [s: string]: A }): (A & {name: string})[] {
  return Object.entries(input)
    .map(a => {
      return {name: a[0], ...a[1]}
    })
}
Moebius
  • 6,242
  • 7
  • 42
  • 54
-1

Just put the response data inside a square bracket and save it in the class.

this.servicename.get_or_post().subscribe(data=>
   this.objectList = [data]);
James Whiteley
  • 3,363
  • 1
  • 19
  • 46
vino
  • 107
  • 1
  • 4
  • 1
    This won't work because it puts the entire "list" into the first entry of the array so you get like `[0:{object1: ...},{object2: ...}]` – DFSFOT Jan 09 '20 at 02:08
-6

Adding toArray() on the pipe worked for me.

// Import toArray function
import { toArray } from 'rxjs/operators';

// Generic function to consume API
searchObjects(term: string): Observable<theObject[]> {
  requestUrl = this.url + term;
  return this.http.get<theObject[]>(requestUrl, httpOptions).pipe(
      // convert object to array
      toArray<theObject>()
  );
}