如何将forkJoin数据分配给变量?

时间:2019-02-06 10:23:41

标签: angular typescript rxjs

我有以下课程:

class ExampleComponent {
    application: Application = new Application();
    company: Company;
    bank_account: BankAccount = new BankAccount();
    contact: Contact;
    director: Director = new Director();
    websites: Website[] = [];
    files: DirectorFile[] = [];
    director_files: DirectorFile[] = [];

    ngOnInit() {
        this.getApplication();
    }

    getApplication() {
        forkJoin([
             this.exampleRepo.getApplication(),
             this.exampleRepo.getCompany(),
             this.exampleRepo.getBankAccount(),
             this.exampleRepo.getContact(),
             this.exampleRepo.getDirector(),
             this.exampleRepo.getAllWebsites(),
             this.exampleRepo.getAllFiles(),
             this.exampleRepo.getDirectorFiles()
         ]).subscribe(
             (data: [
                 Application,
                 Company,
                 BankAccount,
                 Contact,
                 Director,
                 Website[],
                 DirectorFile[],
                 DirectorFile[]
             ]) => {
                 this.application = data[0];
                 this.company = data[1];
                 this.bank_account = data[2];
                 this.contact = data[3];
                 this.director = data[4];
                 this.websites = data[5];
                 this.files = data[6];
                 this.director_files = data[7];
             }
         );
    }
}

然后出现以下错误:

error TS2345: Argument of type '(data: [Application, Company, BankAccount, Contact, Director, Website[], DirectorFile[], DirectorFile[]]) => void' is not assignable to parameter of type '(value: (Observable<Application> | Observable<BankAccount> | Observable<Contact> | Observable<Company> | Observable<Director> | Observable<DirectorFile[]> | Observable<Website[]>)[]) => void'.
  Types of parameters 'data' and 'value' are incompatible.
    Type '(Observable<Application> | Observable<BankAccount> | Observable<Contact> | Observable<Company> | Observable<Director> | Observable<DirectorFile[]> | Observable<Website[]>)[]' is not assignable to type '[Application, Company, BankAccount, Contact, Director, Website[], DirectorFile[], DirectorFile[]]'.
      Property '0' is missing in type '(Observable<Application> | Observable<BankAccount> | Observable<Contact> | Observable<Company> | Observable<Director> | Observable<DirectorFile[]> | Observable<Website[]>)[]'.

如果我未在数据中指定类型,而只写:data => {...},则会出现以下错误:

error TS2322: Type 'Observable<Application> | Observable<BankAccount> | Observable<Contact> | Observable<Company> | Observable<Director> | Observable<DirectorFile[]> | Observable<Website[]>' is not assignable to type 'Application'.
  Type 'Observable<Application>' has no properties in common with type 'Application'.

如果我从forkJoin中删除数组,仅将8个请求作为单个参数添加,我就可以将数据分配给变量,但是随后从linter和rxjs收到一个错误,说与resultSelector的forkjoin是不推荐使用。

关于如何将数据分配给变量的任何想法。如何将Observable数组分解为对象?

2 个答案:

答案 0 :(得分:2)

JavaScript中对象的基本类型是函数。
在代码中,您尝试将“类型的值”分配给“函数”。
为了在您返回 service.ts 中修正类型函数,应返回Observable
例如:

getApplication(): Observable<Application> {}

,然后在 subscribe 函数中的 data 数组将是您的类型,无需分配。

(data) => {
    this.application = data[0];
    ...
}

答案 1 :(得分:1)

当您预订forkjoin时,将返回您为避免这种情况而调用的数据数组,并获得单个可观察值,您只需要销毁数据数组即可,而intellisense错误应该消失,您的错误是传递数据而不是可销毁数据可观察的:

    forkJoin(
      [
        this.service.getProvince(),
        this.service.getLingueStraniere(),
      ]).subscribe(
      ([Province, LingueStraniere]) => {
        this.province = Province;
        this.lingueStraniere = LingueStraniere;
      }
    ); 

现在您的代码应类似于:

forkJoin([
             this.exampleRepo.getApplication(),
             this.exampleRepo.getCompany(),
             this.exampleRepo.getBankAccount(),
             this.exampleRepo.getContact(),
             this.exampleRepo.getDirector(),
             this.exampleRepo.getAllWebsites(),
             this.exampleRepo.getAllFiles(),
             this.exampleRepo.getDirectorFiles()
         ]).subscribe(
             ([
                 application,
                 company,
                 bankAccount,
                 contact,
                 director,
                 website[],
                 directorFile[],
             ]) => {
                 this.application = application;
                 this.company = company;
                 this.bank_account = bankAccount;
                 this.contact = contact;
                 this.director = director;
                 this.websites = website[];
                 this.files = directorFile[];
             }
         ); 

如果您在进行派生之前未指定单个请求的类型,则该接口将无法工作,因此在您的服务中,您定义Application http请求的值将映射到其接口:

 .pipe(map((value: Application) => value))

您需要将数据映射到接口,否则fork连接会给您带来错误,如果您不这样做,则默认类型将是与您在forkJoin中定义的接口类型形成对比的任何类型。