【问题标题】:how to make nested bitbucket API http request in ngrx effects如何在ngrx效果中制作嵌套的bitbucket API http请求
【发布时间】:2021-01-11 11:02:02
【问题描述】:

BitBucket API 1.0 返回没有时间戳的标签。示例响应:

{
  "size": 2,
  "limit": 2,
  "isLastPage": false,
  "values": [
    {
      "id": "refs/tags/tag1",
      "displayId": "tag1",
      "type": "TAG",
      "latestCommit": "ff7be6fad2e660e8139f410d2585f6b2c9867a61",
      "latestChangeset": "ff7be6fad2e660e8139f410d2585f6b2c9867a61",
      "hash": "f13db8e5c0b75b57b48777299d820525ad8127b9"
    },
    {
      "id": "refs/tags/tag2",
      "displayId": "tag2",
      "type": "TAG",
      "latestCommit": "4f5878c9554444755dbf6699eac33ff8752add5f",
      "latestChangeset": "4f5878c9554444755dbf6699eac33ff8752add5f",
      "hash": "23274bd5c9b87614f14a2245d5e70812c83104b7"
    }
  ]
}

因此,我试图请求 latestCommit 以获取它的数据。响应检索我要添加到标记对象的 committerTimestamp。

ngrx效果和如下函数写如下:

@Effect()
  loadTags: Observable<LoadTagsRes> = this.actions$.pipe(
    ofType(BitbucketActionTypes.LOAD_TAGS_REQ),
    switchMap(() => {
      return this.http.get('https://bitbucket/rest/api/1.0/projects/projects/repos/project/tags?limit=2', httpOptions).pipe(
        map((response: any) => response.values.map(tag => (
            {
              ...tag,
              timeStamp: this.getTagTimestamp(tag.latestCommit)
            }
          ))
        ),
        map((response: any) => new LoadTagsRes({tags: response}))
      )
    }),
  );

  getTagTimestamp(tag) {
    return this.http.get<any>(`https://bitbucket/rest/api/1.0/projects/projects/repos/project/commits/${tag}`, httpOptions).pipe(
      switchMap(res => {
        return res;
      })
    );
  }

对象数组中的新 timeStamp 属性在 redux devtools 中显示以下内容:

希望获得内部 http 请求的正确响应。

【问题讨论】:

    标签: javascript angular rxjs ngrx ngrx-effects


    【解决方案1】:

    该函数应触发辅助请求并获取时间戳,但尚未触发。您需要使用switchMap(或任何其他 RxJS 高阶映射运算符)来触发它。并且看到您有多个请求,您可以使用 RxJS forkJoin 函数来并行触发它们。

    试试下面的

    @Effect()
    loadTags: Observable<LoadTagsRes>= this.actions$.pipe(
      ofType(BitbucketActionTypes.LOAD_TAGS_REQ),
      switchMap(() => {
        return this.http.get('https://bitbucket/rest/api/1.0/projects/projects/repos/project/tags?limit=2', httpOptions).pipe(
          switchMap((response: any) => {
            forkJoin(response.values.map(tag =>
              this.getTagTimestamp(tag.latestCommit).pipe(
                map(timeStamp => ({...tag, timeStamp: timeStamp}))
              )
            ))
          }),
          map((response: any) => new LoadTagsRes({
            tags: response
          }))
        )
      }),
    );
    

    【讨论】:

    • 得到以下错误:错误 TS2345:类型“(响应:任意)=> void”的参数不可分配给类型“(值:任意,索引:数字)=> ObservableInput'。类型 'void' 不可分配给类型 'ObservableInput'。试过 switchMap((response: any): any 来避免错误但应用状态没有更新
    • 您似乎试图分配彼此错误类型的变量。请检查返回类型和分配。
    【解决方案2】:
      loadTags: Observable<LoadTagsRes> = this.actions$.pipe(
        ofType(BitbucketActionTypes.LOAD_TAGS_REQ),
        switchMap(() => {
          return this.http.get('https://bitbucket/rest/api/1.0/projects/projects/repos/project/tags?limit=2', httpOptions).pipe(
            mergeMap((response: any) => response.values.map(tag => {
            // array of observables
              const tag$=this.getTagTimestamp(tag.latestCommit);
    
            // use forkJoin to return single observable that returns array of results
             return forkJoin(tag$)
            })
            ),
            map((response: any) => new LoadTagsRes({tags: response}))
          )
        }),
      );
    
      getTagTimestamp(tag) {
        return this.http.get<any>(`https://bitbucket/rest/api/1.0/projects/projects/repos/project/commits/${tag}`, httpOptions).pipe(
          switchMap(res => {
            return res;
          })
        );
    

    【讨论】:

    • 它将以下数组返回到状态:[{_isScalar: false}, {_isScalar: false}]
    猜你喜欢
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多