Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
341 views
in Technique[技术] by (71.8m points)

javascript - how to make nested bitbucket API http request in ngrx effects

BitBucket API 1.0 returns tags with no timestamp. Example response:

{
  "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"
    }
  ]
}

Therefore I am trying to request the latestCommit to get it's data. The response retrieves the committerTimestamp which I want to add to the tag object.

The ngrx effect and a following function are written as follows:

@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;
      })
    );
  }

the new timeStamp property in the array of objects displays the following in redux devtools: enter image description here

Would like to get the correct response for the inner http request.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The function should trigger the secondary request and fetch the timestamp but it isn't being triggered yet. You need to use switchMap (or any other RxJS higher order mapping operator) to trigger it. And seeing that you have multiple requests, you could use RxJS forkJoin function to trigger them in parallel.

Try the following

@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
      }))
    )
  }),
);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...