定义可观察对象后直接在服务中订阅

时间:2018-12-17 14:48:45

标签: angular observable subscribe

在Angular服务的构造函数中,我创建了一个需要直接订阅的可观察对象(无内部订阅)。怎么做? 特别是,在下面的第一段代码中,我具有变量 data.id

this.current_trainee = this.db.collection('Users', ref => ref.where(
  'email', '==',  'EXAMPLE'  )).snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  })
);

现在,我想直接订阅它以在下面的 doc(data.id)”中使用它:

 this.trainees = this.db.collection('Users').doc( data.id ).collection('Trainings_taken').snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  })
);

我尝试通过以下方式订阅:

   this.current_trainee.subscribe(data => this.user_doc_id = data.id );

其中user_doc_id作为空字符串启动。但这不起作用,因为user_doc_id保留为空字符串。有什么建议吗?提前谢谢!

2 个答案:

答案 0 :(得分:0)

因此,基于讨论,我举了一个非常简单的例子。这里的重点是您需要链接第一个响应(给您data.id),并使用它直接调用第二个db函数(而不是使用2个变量)。正如我之前提到的,原因是您对数据库进行了 异步 调用以获取您的ID。这将在稍后的某个时间到达,只有那时您才能使用此ID拨打电话。在当前代码中,您只是立即 立即调用函数this.db.collection('Users').doc( data.id )..},这将无法正常工作。

我没有使用flatMap,因为您没有内在的可观察性(我认为是这种情况)

import { of, Observable } from 'rxjs';
import { mergeMap,map } from 'rxjs/operators';

/**
 * Assume this is the response of the 
 * this.db.collection('Users', ref => ref.where(
 * 'email', '==',  'EXAMPLE'  )).snapshotChanges()
 * i.e an observable output 
 * and data_id is equivalent to data.id in your  
 */
const source = of({data_id: 0}, {data_id:1 },{data_id:2});

/**
 * Now if the data_id is the index to this array, in your case : you need the 
 * data.id to make a call to the `DB` to retrieve the trainees
 */
const db2 = ['a','b','c'];

//use map to get the ID you need and then directly call the db to retrieve trainees, in this case it will return you another observable
const example = source.pipe(map((e,i) =>  of(test(e.data_id))));

// subscribe to the observable and do your action
const subscribe = example.subscribe((val) => console.log(val));

function test(value) {
  return (db2[value]);
}

Stackblitz供您玩耍。

答案 1 :(得分:0)

因此,在一天结束时,请看下面对我有用的内容。尽管它不是很优雅,因为一部分代码会重复出现,但是它可以正常工作,我想结束这个问题。谢谢@ dream88!

this.current_trainee = this.db.collection('Users', ref => ref.where(
  'email', '==',  aux  )).snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  })
  );

this.individual_trainings = this.db.collection('Users', ref => ref.where(
  'email', '==',  aux  )).snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  }),
  switchMap((data) => {
    console.log(data);
    console.log(data[0].id);
    return this.aux2 = this.db.collection('Users').doc(data[0].id).collection('Trainings_taken').valueChanges();
  })
  );