Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested Observables in Angular2 using AngularFire2 not rendering in view

I'm building an experimental (Ionic 2) app that uses Firebase and AngularFire2 (currently in alpha). For this I'm following this tutorial from Aaron Saunders as a basis:

http://www.clearlyinnovative.com/integrating-firebase-with-angularfire2-into-angular2-ionic2-part-2 https://github.com/aaronksaunders/ionic2-angularfire-sample

Below are my home.ts and my home.html.

this.projects = af.list('/items').map( (items) => {
    return items.map( item => {
        item.meta = af.object(`/item_meta/${item.$key}`)
        return item
    })
})

This way of nesting the Observables returns by AngularFire2 was demonstrated in the following presentation: https://youtu.be/ngnSOTSS8Q8?t=1h6m37s

Here is my view:

<ion-card *ngFor="#item of items | async">
    <ion-card-header>
        {{item.name}}
    </ion-card-header>
    <ion-card-content>
        {{item.description}}
        <br>

        {{item.meta.stockPrice | async}}

    </ion-card-content>
</ion-card>

The main difference with the example in the presentation I followed is the fact that I'm nesting an 'object' Observable inside an 'list/array' Observable. Instead they add a list within a list. The consequence of this is that I'm trying to render {{ item.meta.stockPrice }} in my view directly instead of nesting an ngFor.

This is what my data looks like:

{
    "items":
        {
            "item1":{
                "name": "Item 1",
                "description": "1234"
            },
            "item2":{
                "name": "Item 2",
                "description": "abcd"
            }
        }
    "items_meta"{
        "item1":{
            "stockPrice": 1234,
            "moarData": "derp"
        },
        "item2":{
            "stockPrice": 386,
            "moarData": "lolz"
        }
    }
}

I can't seem to figure out why object doesn't want to render. If I output it to JSON it shows that the data is there. Please note that I am new to Angular2 and still wrapping my head around the changes from Angular1. What am I doing wrong?

Edit: I've update the info above and added my data structure to make it more clear

like image 373
DivZero Avatar asked May 05 '16 20:05

DivZero


1 Answers

For your specific issue...

{{(item.meta | async)?.stockPrice}}

use the elvis operator (?) to make sure the async operation is complete and then access the desired value

source code here in github: https://github.com/aaronksaunders/afwithngcli

--

you got ahead of me... working on the new blog post, but here is the code

script.html

</ion-card>
    <ion-card *ngFor="#user of usersWithMessages | async">
    <ion-card-header>
        {{user.displayName}}
    </ion-card-header>
    <ion-card-content>
       {{ (user.messages | async) | json}}
    </ion-card-content>
</ion-card>

script.ts

this.usersWithMessages = this.af.list('/users').map((_users) => {
    return _users.map((_user) => {
        _user.messages = this.af.object("/userObjects/public-messages/" +_user.$key)
        return _user
    })
})

data

   "userObjects" : {
    "public-messages" : {
      "8d75a63e-80cd-40cc-8f8b-87d3d33b0cd0" : {
        "message-id-0" : {
          "text" : "a public message"
        }
      },
      "9c6ea912-ec24-4127-b123-6512ed135f06" : {
        "-KFCGp5ojo7JSX2myOPE" : {
          "date" : "1460511658442.75",
          "text" : "this should be a. public message"
        },
        "-KFCJc4GtEo_PDWi7hru" : {
          "date" : "1460512391529.69",
          "text" : "this is a message that should be public"
        },
        "message-id-100" : {
          "date" : "3243245411111",
          "text" : "public for the other user"
        }
      }
    }
  },
 "users" : {
    "8d75a63e-80cd-40cc-8f8b-87d3d33b0cd0" : {
      "displayName" : "[email protected]",
      "provider" : "password"
    },
    "9c6ea912-ec24-4127-b123-6512ed135f06" : {
      "displayName" : "[email protected]",
      "provider" : "password"
    },
    "cdcf32af-a8cd-467d-a04f-dfc223e890d2" : {
      "avatar" : "https://secure.gravatar.com/avatar/d23563ab3014ce965a90c37b22a34da8?d=retro",
      "displayName" : "[email protected]",
      "provider" : 4
    }
  }
like image 139
Aaron Saunders Avatar answered Sep 28 '22 04:09

Aaron Saunders