2017-01-26 52 views
1

我有存儲在2個不同數據庫上的等效數據類型。如何完成2個http請求,然後觸發另一個操作來合併結果

  • SQL數據庫,我儲存的所有食物的一個巨大的列表。
  • On a Mongo數據庫我正在儲存個人的食物數據,這將會覆蓋所提供的默認食物數據 。

這兩種類型的數據都將存儲在我的ngrx存儲應用程序狀態以及合併狀態中。

export interface ApplicationState { 
    allSQLFoodData: FoodData; 
    allUserFoodData: FoodData; 
    mergedFoodData: FoodData; 
} 

我需要做的,是讓從後端的allSQLFoodDataallUserFoodData,這些值存儲的狀態以及在合併狀態合併這兩組數據。

我正在通過dispatch()執行此操作INITIALIZE_DATA_ACTION然後我在效果服務中收聽。

這裏就是我站在我的效果服務:

初始化數據效果的service.ts

@Injectable() 
export class InitializeDataEffectService { 

    @Effect() initialize$: Observable<Action> = this.actions$ 
    .ofType(INITIALIZE_DATA_ACTION) 
    .switchMap((action) => { 
     return Observable.combineLatest(
     this.foodService.loadSQLFoods(action.payload), 
     this.userDataService.loadUserData(action.payload) 
    ) 
    }) 
    .switchMap(([allSQLFoodData, allUserData]) => { 
     return Observable.of(
     new SQLFoodsLoadedAction(allSQLFoodData), 
     new UserDataLoadedAction(allUserData), 
     new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData}) 
    ) 
    }) 

    constructor(private actions$: Actions, private foodService: FoodService, private userDataService: UserDataService) { 

    } 
} 

正如你所看到的,我聽了INITIALIZE_DATA_ACTION類型的動作並使用響應中的combineLatest()創建組合觀察值。然後我調用Action類設置每個應用程序的狀態:

.switchMap(([allSQLFoodData, allUserData]) => { 
    return Observable.of(
    new SQLFoodsLoadedAction(allSQLFoodData), 
    new UserDataLoadedAction(allUserData), 
    new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData}) 
) 
}) 

但是,這是給下面的錯誤:

The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'SQLFoodsLoadedAction' is not a valid type argument because it is not a supertype of candidate 'UserDataLoadedAction'. Types of property 'payload' are incompatible. Type 'AllUserData' is not assignable to type 'AllSQLFoodData'. Property 'foods' is missing in type 'AllUserData'.

我不知道如何

specifying the type arguments explicitly

即使我做了,我也不確定裝飾器現在將如何將結果分配給適當的狀態值。 我該如何做到這一點?

回答

3

要從switchMap發射從效果多個動作返回可觀察到的,使用Observable.from,這可能需要一個磁盤陣列:

import 'rxjs/add/observable/from'; 
import 'rxjs/add/operator/concatMap'; 

... 
.concatMap(([allSQLFoodData, allUserData]) => Observable.from([ 
    new SQLFoodsLoadedAction(allSQLFoodData), 
    new UserDataLoadedAction(allUserData), 
    new BuildMergedFoodDataAction({sql: allSQLFoodData, user: allUserData}) 
])) 

注意,switchMap是不必要的,因爲返回的可觀察到的將立即發出。相反,您可以使用concatMap

此外,該效果不分配任何狀態。它唯一的作用是發出行動。這些操作將由reducer處理,這些reducers將更新應用程序狀態的相應部分。

相關問題