Home Read object field from observable using async pipe
Reply: 0

Read object field from observable using async pipe

user7432
1#
user7432 Published in September 21, 2018, 8:27 am

I want to gain a better understanding of when to use the async pipe in Angular.

I love the idea of having data appear asynchronously to the view by simply adding a pipe that subscribes to the data.

However, I have only ever seen and properly applied the async pipe on network request, or some other custom observable, that contains either an array of data or a single field (like an observable string).

For example:

Lets say I make an API call that returns an array of college students.

// This data is within a network response
$students = ...get...map... 
[
  {
    name: "Bob OConnel",
    id: 0,
    description: "young..."
  },
  {
    name: "Rick Luckard",
    id: 3,
    description: "young..."
  },
  {
    name: "James Wing",
    id: 2,
    description: "young..."
  }
]

This could be displayed in a template like so:

<tr *ngFor="let student of $students | async">
  <td>{{student.id}}</td>
  <td>{{student.name}}</td>
  <td>{{student.description}}</td>
</tr>

However, given the ole REST API philosophy. I have yet to ever make a production API call that returns just an array of data. There are always fields on the same level as the array of data. But they're there for a reason, I dont want to simply throw those extra fields away in a Mapping.

So instead of $students being an array, it would become:

// This data is within a network response
$students = ...get...map... 
{
  id: "69asdkasdkljasd6969"
  href: "someURLrepresentingTheDatasOrigins"
  length: 3
  items: [
    {
      name: "Bob OConnel",
      id: 0,
      description: "young..."
    },
    {
      name: "Rick Luckard",
      id: 3,
      description: "young..."
    },
    {
      name: "James Wing",
      id: 2,
      description: "young..."
    }
  ]
}

So this means that in the template, I can throw an async pipe on the $students observable, but not on the fields within it.

This obviously doesnt work, because the fields within the observables are observables:

{{$students.id| async}}
// or
<tr *ngFor="let student of $students.items | async">...</tr>

So, does that mean that on network responses like that, I should map the values of the response out into their own individual observables if I want to asynchronously bind to them in a template? Is there any way around that if I dont want the network response to split into a million smaller objects (Or in the case of my example: {id, length, href} and {items}).

It feels as if I am missing something obvious about the usage of observables that would clear up this issue for me. Let me know if my question is not clear enough.

UPDATE I found something i didnt know I could do here: https://toddmotto.com/angular-ngif-async-pipe

Super helpful for situations where some sort of loading indicator should be in the place of async data. It also works to consolidate subscriptions into one place. That would be a matter of preference, but I think in many of my situations I would prefer to throw the subscription into an *ngIf.

Unless you can do that same else template logic into an *ngFor..?

share|improve this question

1 Answer 1

active oldest votes
up vote 6 down vote accepted
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.341883 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO