编辑:有关解决方案,请参阅库尔特·汉密尔顿的答案。
我正在调用API以返回settings.service.ts中某些设置的值。在settings.component.ts中,需要返回这些内容以填写表单-当API调用尚未完成时,它会显示正在加载。
它正在与'return of(fakeData)'一起使用。但是,我不知道如何返回“ realData”。
而不是console.log(realData),我要返回该值而不是fakeData。
一些帮助会很好,在此先谢谢您!
下面是代码的相关部分。
settings.service.ts:
export interface Settings {
setting1: boolean;
setting2: string;
}
const fakeData = {
setting1: true,
setting2: 'test'
};
@Injectable()
export class SettingsService {
defaultSettings: DefaultSettings[];
constructor(private apiService: ApiService) { }
loadSettings(): Observable<Settings> {
this.apiService.getDefaultSettings().subscribe( defaultSettings => {
// defaultSettings is needed for when value1 or value2 is 'null'
// not implemented yet, but therefore this nested subscription structure
this.defaultSettings = defaultSettings;
const value1 = this.apiService.getSpecificSetting('setting1');
const value2 = this.apiService.getSpecificSetting('setting2');
forkJoin([value1, value2]).subscribe( result => {
const realData = {
setting1: result[0],
setting2: result[1],
};
console.log(realData);
// return of(settingsFound); not possible here ...
});
});
return of(fakeData);
}
}
settings.component.ts
settings: Observable<Settings>;
ngOnInit() {
this.settings = this.settingsService.loadSettings().pipe(
tap(settings => {
this.settingsForm.patchValue(settings);
})
);
}
使用concatMap
或switchMap
在另一个可观察对象之后运行新的可观察对象(在您的情况下为forkJoin
。
@Injectable()
export class SettingsService {
defaultSettings: DefaultSettings[];
constructor(private apiService: ApiService) { }
loadSettings(): Observable<Settings> {
return this.apiService.getDefaultSettings().pipe(
// save default settings
// this may not be required if you only need default settings for the forkJoin
tap(defaultSettings => this.defaultSettings = defaultSettings),
// now run the next observable
concatMap(defaultSettings => {
return forkJoin({
setting1: this.apiService.getSpecificSetting('setting1'),
setting2: this.apiService.getSpecificSetting('setting2')
});
}),
// now map the result of the forkJoin to the value to want to return
// map won't be required in this case,
// as the arg going into forkJoin matches the desired return structure
// I left it in for completeness
map(result => {
const realData = {
setting1: result.setting1,
setting2: result.setting2,
};
console.log(realData);
return realData;
})
);
}
}
压缩版
没有我的注释和多余的调用,完成的结果看起来像这样:
@Injectable()
export class SettingsService {
constructor(private apiService: ApiService) { }
loadSettings(): Observable<Settings> {
return this.apiService.getDefaultSettings().pipe(
concatMap(defaultSettings => forkJoin({
setting1: this.apiService.getSpecificSetting('setting1'),
setting2: this.apiService.getSpecificSetting('setting2')
}))
);
}
}