Angular 链接到重构的两个订阅

Angular 链接到重构的两个订阅,angular,rxjs,Angular,Rxjs,我尝试用两个订阅(一个在方法中,一个在服务中)重构下面的代码,但我找不到方法 我用它来处理我的状态。因此,建议在中提到的服务中使用订阅 此代码用于处理非规范化的情况:MongoDB服务集合中用户集合的my language字段 以下是我使用的模型: 用户模型 export interface UserInfo { [...] services: ID[]; } export interface User { _id: ID; [...] userInfo: Partial&

我尝试用两个订阅(一个在方法中,一个在服务中)重构下面的代码,但我找不到方法

我用它来处理我的状态。因此,建议在中提到的服务中使用订阅

此代码用于处理非规范化的情况:MongoDB服务集合中用户集合的my language字段

以下是我使用的模型:

用户模型

export interface UserInfo {
  [...]
  services: ID[];
}

export interface User {
  _id: ID;
  [...]
  userInfo: Partial<UserInfo>;
}
export interface ServiceInfo {
  [...]
  userFamilyName: string;
  userGivenName: string;
  userLanguages: Language[];
}

export interface Service {
  _id: ID;
  [...]
  serviceInfo: Partial<ServiceInfo>;
}
但是我被困在
实体.userInfo.services.forEach

有办法吗


感谢您的帮助。

每当您在服务中看到订阅时,可能代码有问题。您需要使用
.tap()
来执行一些副作用操作。永远不要在服务中订阅,让组件处理订阅

在职:

addLanguage(service: Service) {
    const url = `${this.servicesUrl}/${service._id}/languages`;
    const accessToken = this.authQuery.getSnapshot().accessToken;
    this.http.post<Service>(url, service, {
        headers: new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': accessToken
        })
    })
        .pipe(
            tap((entity: Service) => {
                if (this.servicesQuery.hasEntity(service._id)) {
                    this.servicesStore.update(service._id, entity);
                }
            })
        );
}

您是否关心(entity.userInfo.services)是否等于false?不正确?另外,如果您的服务的
addLanguage
返回一个
服务
类型,为什么它在组件处作为
用户
类型进行检索?我使用此代码处理我的语言字段的非规范化(MongoDB中服务集合中的用户集合)实际上,
entity.UserInfo.services
已经是一个数组。对于您的解决方案,我有一条错误消息:“Service[]”类型的参数不能分配给“Service”类型的参数。我编辑我的帖子是为了提供更多的信息。@jodandelion啊,我错了。我已经编辑了答案。非常感谢。它起作用了!我不知道forkJoin接线员的事。现在,我知道了:)我还有一个问题。当我的用户中没有服务时,订阅未到达是否正常?(用户模式下的服务未定义或为空)。语言form.reset();这是onNavigateBack();在这种情况下不会被解雇。我更新了我最初的帖子,向你们展示了我的真实版本。@jodandelion是的
forkJoin()
将等待所有可观察对象完成,然后再发射。如果需要,可以尝试
CombineTest()
addLanguage(service: Service) {
  const url = `${this.servicesUrl}/${service._id}/languages`;
  const accessToken = this.authQuery.getSnapshot().accessToken;
  this.http.post<Service>(url, service, {
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': accessToken
    })
  }).subscribe(
    (entity: Service) => {
      if (this.servicesQuery.hasEntity(service._id)) {
        this.servicesStore.update(service._id, entity);
      }
    }
  );
}
this.usersService.addLanguage(user).pipe(
  filter((entity: User) => entity.userInfo.services !== undefined),
  switchMap((entity: User) => {
    entity.userInfo.services.forEach(serviceId => {
      const service = createService({
        _id: serviceId,
        serviceInfo: {
          userLanguages: [language]
        }
      });

      return this.servicesService.addLanguage(service);
    })
  }
);
addLanguage(service: Service) {
    const url = `${this.servicesUrl}/${service._id}/languages`;
    const accessToken = this.authQuery.getSnapshot().accessToken;
    this.http.post<Service>(url, service, {
        headers: new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': accessToken
        })
    })
        .pipe(
            tap((entity: Service) => {
                if (this.servicesQuery.hasEntity(service._id)) {
                    this.servicesStore.update(service._id, entity);
                }
            })
        );
}
private addLanguage(languageForm: FormGroup) {
    this.usersService.addLanguage(user).pipe(
        takeUntil(this.ngUnsubscribe),
        //filter away the conditions  
        filter((entity: User) => entity.userInfo.services),
        switchMap((entity: User) => {
            //use .map() to create an array of services.
            let serviceObs$ = entity.UserInfo.services.map(serviceId =>
                this.servicesService.addLanguage(createService({
                    _id: serviceId,
                    serviceInfo: {
                        userLanguages: [language]
                    }
                })));
            //use forkJoin to combine all of them
            return forkJoin(serviceObs$);
        })
    ).subscribe(() => {
            languageForm.reset();
            this.onNavigateBack();
        }
    );
}