1

How do I display the id and title of the below Hero object? The Hero interface below is mapped according to Firebase JSON response.

hero.component.ts

import {Component, Input} from 'angular2/core';
import {Hero} from '../model/hero';

@Component({
  selector: 'hero-component',
  template: `
                {{hero | json }} this works. This display the Firebase JSON response as seen below 
                <br>
                {{ Object.keys(hero)[0] }} this DOESN'T work
                <br> 
                {{ hero[Object.keys(hero)[0]].title }}this also DOESN'T work
  `
})

export class HeroComponent {
  @Input()
  hero:Hero;
}

hero.ts

export interface Hero {
  [id: string]: {
    createdAt: number;
    isActive: boolean;
    title: string;
    updatedAt: number;
  }
}

Firebase JSON response

{ "-KEMOfA5KFK98AXNhPY0": { "createdAt": 1459607745222, "isActive": true, "title": "Wind Hero", "updatedAt": 1459607745222 } } 
Jek
  • 5,546
  • 9
  • 37
  • 67
  • One point to note, I'm not using AngularFire2. I'm using Firebase REST API. I had a hard time using Angular2 with Firebase REST API because I don't know how to map Firebase JSON response to Typescript Interface and also accessing the variables. Would it have been easier if I used AngularFire2? – Jek Apr 07 '16 at 16:26
  • 1
    Why don't you use Firebase from a service, and make the service transform the response and return in a more usable format? That would isolate the controller and view code from these firebase concerns. – JB Nizet Apr 07 '16 at 16:28
  • Good idea. I'm not very familiar with Angular2 and Firebase. So what I am able to do now is follow whatever screencast I find. @JB Nizet how would you do it? do you have a Github repo for this suggestion? – Jek Apr 08 '16 at 01:01
  • 1
    No. I've never used Firebase. But you would do something similar to what is described [in the doc](https://angular.io/docs/ts/latest/guide/server-communication.html#!#map) for using Http (in a service, make your request, and transform the response data to JSON), except here, the service would call firebase, and transform the returned firebase array to a more usable object. – JB Nizet Apr 08 '16 at 05:42

2 Answers2

0

update

instead of pipes: [KeysPipe]

use

@NgModule({
  declarations: [KeysPipe],
  exports: [KeysPipe],
}
export class SharedModule{}
@NgModule({
  ...
  imports: [SharedModule],
})

original

You can't use Object.keys(hero)[0] in the template. No global references can be used, only members of the component.

Instead create a function on your component

getKeys(obj) {
  return Object.keys(obj);
}

and then in the template

{{ getKeys(hero)[0] }}

Alternatively you can build a pipe that extracts the keys like for example https://stackoverflow.com/a/34074484/217408

@Pipe({ name: 'keys',  pure: false })
export class KeysPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value);
  }
}

then use it like

{{ (hero | keys)[0] }}

Don't forget to add the pipe to pipes: [KeysPipe] on the component where you want to use it or alternatively

bootstrap(App, [provide(PLATFORM_PIPES, {useValue: KeysPipe, multi:true})]);
Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
-1

Your code isn't working since Object isn't available in your component.

You could try something like this:

@Component({
  selector: 'hero-component',
  template: `
            {{hero | json }} this works. This display the Firebase JSON response as seen below 
            <br>
            {{ obj.keys(hero)[0] }} this DOESN'T work
            <br> 
            {{ hero[obj.keys(hero)[0]].title }}this also DOESN'T work
  `
})
export class HeroComponent {
  @Input()
  hero:Hero;

  obj = Object;
}

or using a method like Günter suggested in his answer.

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Doesn't work. obj = Object. It throws error EXCEPTION: TypeError: can't convert undefined to object in [ {{ obj.keys(hero)[0] }} – Jek Apr 16 '16 at 01:34
  • 1
    It works for me. See this plunkr: https://plnkr.co/edit/bUQd2XOronpjv2GvdhJa?p=preview. I think that there is another problem. Perhaps because of the way you load the `hero` object (asynchronously). So initially the object is undefined and it's set after... – Thierry Templier Apr 16 '16 at 06:46
  • I will try it on my end again. Thanks Thierry :) – Jek Apr 21 '16 at 01:40