javascript - Retrieve value inside Observable - Stack Overflow

I make a request to the server and get the response as observable. Inside the data, I have an ID which

I make a request to the server and get the response as observable. Inside the data, I have an ID which refers to another document, which I need to send another request to fetch the data and append it with the data of the parent Observable. How to achieve this?

With Promise, I can use async/await to do this, but I want to know how to achieve this using Observables

Sample with promise

async func_name() {
  let data1 = await <first_server_call_returns_promise>();
  let data2 = await <second_call_with_data1.id_returns_promise>();
  data1.value = data2;
  return data1;
}

I make a request to the server and get the response as observable. Inside the data, I have an ID which refers to another document, which I need to send another request to fetch the data and append it with the data of the parent Observable. How to achieve this?

With Promise, I can use async/await to do this, but I want to know how to achieve this using Observables

Sample with promise

async func_name() {
  let data1 = await <first_server_call_returns_promise>();
  let data2 = await <second_call_with_data1.id_returns_promise>();
  data1.value = data2;
  return data1;
}

How to achieve the above with Observables?

Edit 1

Based on @TeddySterne reply the code I wrote is below but I'm getting an observable within the subscribe instead of actual data which prevent me to assign the observable to html

this.blogDoc.snapshotChanges().pipe(
    exhaustMap((blogs) => {
        return blogs.map(blog => {
          const data = blog.payload.doc.data();
          const id = blog.payload.doc.id;
          return this.userService.getUserById(data.uid).pipe(
            map((user) => {
              const name = user.name;
              return { id, name, ...data}
            }),
          )
        })
    }),
  )
  .subscribe(finalData => {
    finalData.subscribe(data => console.log(data));
  });

Edit 2

Below is the updated code that I have now

this.blogDoc.snapshotChanges().pipe(
      exhaustMap((blogs: any[]) => {
        return zip(blogs.map((blog) => {
          const data = blog.payload.doc.data();
          const id = blog.payload.doc.id;
          console.log(data);
          return this.userService.getUserById(data.uid).pipe(
            map((value) => {
              console.log(value);
              return value;
            })
          )
        })).pipe(first())
      })
    ).subscribe(values => console.log("Values: ", values));

The console.log(data) prints the data correctly but console.log(value) is not getting printed nor the console.log("Values: ", values)

When I use subscribe on this.userService.getUserById(data.uid), it returns the expected single user document.

What am I missing here?

Share Improve this question edited May 11, 2018 at 21:30 Sesha asked May 10, 2018 at 19:34 SeshaSesha 5661 gold badge7 silver badges22 bronze badges 2
  • You can't, unless you convert them .toPromise(). – jonrsharpe Commented May 10, 2018 at 19:39
  • Its not necessary that I should use async/await. If there's any other possible way? – Sesha Commented May 10, 2018 at 19:41
Add a ment  | 

2 Answers 2

Reset to default 4

You can use an exhaustMap to pipe the data to a second http call and then merge the data together when it returns.

Example

import { zip } from 'rxjs/observable/zip';

this.http.get('/data1').pipe(
  exhaustMap((data1Arr: any[]) => {
    return zip(...data1Arr.map((data1) => {
      return this.http.get('/data2/' + data1.id).pipe(
        map((data2) => {
          data1.value = data2;
          return data1;
        }),
      );
    }).pipe(first());
  }),
).subscribe((fullQualifiedData) => {
  // do stuff with the data
});

Example

I tried the above code, but what I'm getting in fullQualifiedData is another observable, which I can't use directly on *ngFor in html file.

This is discussed in the Angular docs as well, but essentially you have two solutions:

Using the async pipe

The async pipe will subscribe to the observable for you and then provide the data. This is easy to use, but note that every async pipe will create a new subscription, which in the case of HTTP requests can mean firing that request multiple times. So use with care.

@Component({ … })
export class YourComponent {
  public data$ = this.http.getFoo();

  constructor(private http: Http) {}
}
<ng-container *ngIf="data$ | async as data">
    {{ data.foobar }}
</ng-container>

Manually managing the subscription

@Component({ … })
export class YourComponent implements OnInit {
  public data: Data;

  constructor(private http: Http) {}

  public ngOnInit() {
    this.http.getFoo().subscribe(data => this.data = data);
  }
}
{{ data?.foobar }}

or

<ng-container *ngIf="data">
  {{ data.foobar }}
</ng-container>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744794079a4594096.html

相关推荐

  • javascript - Retrieve value inside Observable - Stack Overflow

    I make a request to the server and get the response as observable. Inside the data, I have an ID which

    2天前
    60

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信