Angular Wordpress REST API - 如何使用新标签创建 post(结合 Observables)?

Angular Wordpress REST API - How to create a post with new tags (combine Observables)?

我有一个与 Wordpress REST API 对话的 Angular 应用程序。该应用需要创建一个新的 post 以及 0-3 个新标签。我说 0 是因为在这种情况下标签是可选的。如果用户决定包含标签,则标签数量不得超过 3 个。我的应用程序与 Whosebug 的工作方式类似,因为我不会处理 post 和评论,而是指“问题”和“答案”。

流程如下:

  1. 用户输入标题,body 和模板中新“问题”的可选标签。标签将被键入 tag-name-1,tag-name2

  2. 按钮 (click)="saveQuestion(title.value, tags.value)" 触发对组件的函数调用。

  3. 组件中存在以下代码:

    saveQuestion(title: string, tags: string) {
    
        // value is now an array of strings: ["tag-name-1","tag-name-2"]
        let splittedTags = tags.split(",");
    
        let tagData = [];
    
        for (let i = 0; i < splittedTags.length; i++) {
            // value is now [{"name": "tag-name-1"}, {"name": "tag-name-2"}]
            tagData.push({"name": splittedTags[i]});
        }
    
        // component has an empty array variable called tempArray = [];
        for (let i = 0; i < 3; i++) {
            if (i == 3) { break; }
            // use Tag interface to type the code
            this.questionService.addTag(tagData[i] as Tag)
                .subscribe(tagResponse => {
                this.tempArray.push(tagResponse.id)
            })
        }
    
        // IMPORTANT: this returns an empty array variable when we need an array of numbers
        console.log("tempArray: " + JSON.stringify(this.tempArray));
    
        // get title and content from the template
        // tempArray should be an array of strings, which we got from previous loop of subscribe() methods
        let questionData = {
            "date": new Date().toJSON(),      
            "status": "publish",
            "title": title,
            "content": this.html,
            "tags": this.tempArray
        }
    
        this.questionService.addQuestion(questionData as NewQuestion)
            .subscribe(response => { console.log(response) })
    
    }
    

所以我们首先从模板中捕获标签名称字符串"tag-name-1,tag-name-2",然后将其放入一个objects的数组中。然后我们调用服务的 addTag() 函数(与标签一样多)它调用 Wordpress REST API 并创建一个新标签:

private questionsUrl = 'http://localhost/wordpress/wp-json/wp/v2';

httpOptionsAuth = {
    headers: new HttpHeaders({
      'Authorization': `Basic ${btoa("username:password")}`,
      'Content-Type': 'application/json'
    })
}

addTag(tag: Tag): Observable<any> {
    return this.http.post<Tag>(`${this.questionsUrl}/tags`, tag,
    this.httpOptionsAuth)
}

调用 /tags API 在 return 中为我们提供新创建标签的编号 ID。我们需要将这些数字 ID 放入一个数组中,然后最后调用服务的 addQuestion() 方法:

addQuestion(newquestion: NewQuestion): Observable<NewQuestion> {
    return this.http.post<NewQuestion>(`${this.questionsUrl}/posts`, newquestion,
      this.httpOptionsAuth);
}

简而言之,我的问题是:是否有方便的 RxJS 运算符可以负责组合 Observables?

你可以这样做:

saveQuestion(title: string, tags: string) {

  // value is now an array of strings: ["tag-name-1","tag-name-2"]
  let splittedTags = tags.split(",");

  from(splittedTags)
    .pipe(
      take(3), // <-- take first 3 tags max
      map((tag) => ({"name": tag})), // <-- map tag string to Tag
      mergeMap( // <-- save tags and extract returned id from responses
        (tag) => this.questionService.addTag(tag as Tag).pipe(
          map((tagResponse) => tagResponse.id)
        )
      ),
      toArray(), // <-- group returned ids into one array
      concatMap( // <-- final save request
        (tagIds) => {
          const questionData = {
            "date": new Date().toJSON(),      
            "status": "publish",
            "title": title,
            "content": this.html,
            "tags": tagIds
          }

          return this.questionService.addQuestion(questionData as NewQuestion)
        }
      )
    )
    .subscribe(console.log);
 }  

干杯