用嵌套数组链接rxjs 6观测值

用嵌套数组链接rxjs 6观测值,rxjs,observable,Rxjs,Observable,我必须对API执行3个相关请求 第一次检索用户id的数组 第二种方法必须迭代用户id的数组,每次检索一个与用户相关的项目id数组 第三种方法必须迭代项目id的数组并检索与项目相关的数据 我想要这样的结果: [{'username': 'richard', projects: [{"id": 1, "name": "test"}]}, ...] 但我完全被mergeMap、forkJoin等所困扰 我尝试过的事情: getUserTeamMembers(): Observable<any&

我必须对API执行3个相关请求

  • 第一次检索用户id的数组
  • 第二种方法必须迭代用户id的数组,每次检索一个与用户相关的项目id数组
  • 第三种方法必须迭代项目id的数组并检索与项目相关的数据
  • 我想要这样的结果:

    [{'username': 'richard', projects: [{"id": 1, "name": "test"}]}, ...]
    
    但我完全被mergeMap、forkJoin等所困扰

    我尝试过的事情:

    getUserTeamMembers(): Observable<any> {
    return this.http.get(`${environment.serverUrl}/user/profil`).pipe(
      mergeMap((teamUsers: any) =>
        this.http.get(
          `api/user/${teamUsers.data._id}/team`
        )
      ),
      mergeMap((teamUsers: any) =>
        forkJoin(
          ...teamUsers.data.map((user: any) =>
            this.http.get(`api/user/${user.id}`)
          )
        )
      ),
      map((res: any) =>
        res
          .map((user: any) => {
            if (user.data) {
              return {
                firstname: user.data.local.firstname,
                lastname: user.data.local.lastname,
                email: user.data.local.email,
                projects: user.data.local.projects,
                language: user.data.local.lang
              };
            }
          })
          .filter((user: any) => user !== undefined)
      ),
      tap(t => console.log(t)),
      catchError(err => throwError(err))
    );}
    

    我举了一个类似的例子,希望它能澄清这个想法

    当然,没有使用http,而是使用of

    并将最终结果存储在名为
    results

    我们有一个获取所有用户列表的源,另一个提供用户id的源将返回此用户项目id的列表
    projectList
    ,最后一个提供一个项目id的源将返回其详细信息(
    projcectsDetails

    let users=of([1,2,3])
    让projectsList=(userId)=>of([userId,userId*2])
    让projectsDetails=(projectId)=>of({id:projectId,details:`details about${projectId}`})
    让结果=[];
    使用者
    .烟斗(
    点击(用户=>{
    users.forEach(userId=>results.push({userId,projects:[]}));
    返回用户
    }),
    switchMap(users=>forkJoin(users.map(userId=>projectsList(userId))),
    开关映射(projectsArray=>forkJoin(
    projectsArray.map(
    oneProjectArray=>
    forkJoin(oneProjectArray.map(projectd=>projectsDetails(projectd)))
    )
    )
    ),
    轻触(projectDetailsArray=>{
    projectDetailsArray.forEach((projectsArray,索引)=>{
    结果[索引]['projects']=[…projectsArray]
    })
    })
    )
    .subscribe(()=>console.warn('final',results))
    
    解释

      1- initalize the result array from the given users
      [ 
       { userId: X, projcts: [] }, 
       { userId: Y, projcts: [] }, 
        ....
      ]
    
      2- for each give users we want the projects ids he/she has
      so the first switchMap will return (in order)
      [
       [ 1, 2, 3, ...] project ids for the first user,
       [ 8, 12, 63, ...] project ids for the second user,
       ...
      ]
    
      3- in the second switchMap we iterate over the previous array
      (which is an array that each item in it is an array of projects ids)
    
      so we needed two forkJoin the outer will iterate over each array of projects ids(the big outer 
      array previously mentioned)
      the inner one will iterate over each single project id and resolve it's observable value(which is the
      project details)
    
      4- finally in the tap process we have an array of array like the 2nd step but this time each
      array has the projects details and not the projects ids
    
      [
       { userId:1, projects: [ { id:1, details: 'details about 1' }, { id:2, details: 'details about 2' }]},
       { userId:2, projects: [ { id:2, details: 'details about 2' }, { id:4, details: 'details about 4' }]},
       { userId:3, projects: [ { id:3, details: 'details about 3' }, { id:6, details: 'details about 6' }]}
      ]
    

    优秀的回答和很好的解释,但我认为没有必要把答案搞砸了。只是一个意见:)谢谢您的时间,我现在有一个错误,当我执行最后2次forkJoin时,我的db被正确调用,但我的所有请求都被取消,因此当我最终点击时,结果中没有任何内容。@amerej抱歉,是我的错。switchMap将取消以前的请求或事件,因此请尝试使用mergeMap而不是第二个switchMap,如果可以,请告诉我更新答案。@LouayAlosh是的,它可以与merge map一起使用,但现在,我找不到创建结果数组的方法,如果我在tap中返回结果,它将返回良好的结果,但次数与他在上次mergeMap中找到的结果相同,如果我不返回结果,它将返回一个未定义的数组:(@amerej问题是,在上次tap中projectDetailsArray是否按您需要的顺序返回您想要的结果?
      1- initalize the result array from the given users
      [ 
       { userId: X, projcts: [] }, 
       { userId: Y, projcts: [] }, 
        ....
      ]
    
      2- for each give users we want the projects ids he/she has
      so the first switchMap will return (in order)
      [
       [ 1, 2, 3, ...] project ids for the first user,
       [ 8, 12, 63, ...] project ids for the second user,
       ...
      ]
    
      3- in the second switchMap we iterate over the previous array
      (which is an array that each item in it is an array of projects ids)
    
      so we needed two forkJoin the outer will iterate over each array of projects ids(the big outer 
      array previously mentioned)
      the inner one will iterate over each single project id and resolve it's observable value(which is the
      project details)
    
      4- finally in the tap process we have an array of array like the 2nd step but this time each
      array has the projects details and not the projects ids
    
      [
       { userId:1, projects: [ { id:1, details: 'details about 1' }, { id:2, details: 'details about 2' }]},
       { userId:2, projects: [ { id:2, details: 'details about 2' }, { id:4, details: 'details about 4' }]},
       { userId:3, projects: [ { id:3, details: 'details about 3' }, { id:6, details: 'details about 6' }]}
      ]