传递动作有效负载时,ngrx效果调度操作错误和null

时间:2018-03-14 02:44:21

标签: angular httpclient ngrx ngrx-effects

我有这种效果,如果最后的帖子成功,就会调度一个虚拟动作。

@Effect() post$: Observable<Action> = this.actions$
        .ofType(PropertyActions.UPLOAD_FILE_GETSIGNEDURL)
        .switchMap((action: PropertyActions.UploadFileGetsignedUrl) => {
            this.actionData = action.payload;
            return this.authService.getAuthenticatedUser().getSession((err, session) => {
                if (err) {
                return;
                }

                // post to API gateway
                return this.httpClient.post('https://abcd.execute-api.us-east-1.amazonaws.com/dev/', {
                    title: 'foo',
                    body: 'bar',
                    userId: 1
                    })
                    .pipe(map(res => {
                            console.log("res from signed url: " + res);
                            this.httpClient.post(res.toString(), this.actionData)
                            .pipe(map(res => {
                                console.log("res from upload: " + res);
                                return new PropertyActions.OpenAllProperties(res);
                            }))
                            //return new PropertyActions.OpenAllProperties(res);
                        },
                        err => {
                            console.log("Error occured");
                            return new PropertyActions.OpenAllProperties(null);
                        })
                    );
                }
            )
        }
    )

但是有两件事是错的:

  1. 我收到此错误:ERROR错误:效果“PropertyEffects.post $”调度了无效操作:undefined core.js:1427错误类型错误:操作必须是对象 步骤经过最内层的帖子后,在控制台中生成此错误:this.httpClient.post(res.toString(),this.actionData)。 另请注意,内部console.log永远不会被点击

  2. 我试图将第一个回调的action.payload传递到最内层的帖子但是得到null。 this.actionData是我使用以下组件设置的组件的变量:

  3. @Injectable()
    export class PropertyEffects {
    
        private actionData: string;
    
        constructor(
            private actions$: Actions,
            private httpClient: HttpClient,
            private store: Store<fromApp.AppState>,
            private authService: AuthService
        ){}
    
        @Effect() post$: Observable<Action> = this.actions$
        ...

    如何将action.payload传递到最里面的帖子? 预先感谢您的帮助!我是Angular和Rxjs的新手,所以感谢你的时间。

2 个答案:

答案 0 :(得分:4)

你不应该以这种不利于测试和重用的方式混乱你的效果,尝试删除对服务的HTTP调用并注入然后在你的效果中使用它。 假设你把它放在MyHttpService中就像这样

@Injectable()
export class MyHttpService {
  constructor(private http: HttpClient) {
  }        

  addItem(payload: AddItemPayload): Observable<AddItemSuccessPayload> {  
    return this.http.post<AddItemSuccessPayload>('/api/items/' + payload.id, payload.Data).pipe(
      map((data) => {
        return {item: data.item};
      })
    );
  }
}

现在我们将其注入效果并将action.payload传递给服务内部,如果错误或成功我们将其发送给其他效果

 @Injectable()
 export class VendorEffect {

  @Effect() 
  addItem$ = this.actions$.pipe(
    ofType(Vendor.ActionType.ADD_ITEM),
    map((action: Vendor.AddItem) => action.payload),
    exhaustMap((request) =>
      this.myHttpService.addItem(request).pipe(
        map(payload => new Vendor.AddItemSuccess(payload)),
        catchError(err => of(new Vendor.AddItemFail(err)))
      )
    )
  );


      constructor(private actions$: Actions, private myHttpService: MyHttpService) {
      }

    }

这就是它,这就是现在使用ngrx使用带有ofType

的管道的方法

答案 1 :(得分:0)

在原始问题中,

最里面的帖子:this.httpClient.post(res.toString(), this.actionData)可能返回undefined或为空。 Angular Effect希望您通过返回操作来处理此类情况。您可以按照以下步骤进行操作:

return new ErrorAction({msg: "Data could not be loaded"})

在您的ErrorAction中:

export class ErrorAction implements Action {
    readonly type = ActionTypes.ErrorAction;
    msg: String;
    constructor(error: any) {
        this.msg = error.msg;
    }
}

然后,最后订阅ErrorAction类型并显示错误消息。您可以如下使用NotificationsService

this.actions.pipe(ofType(ActionType.ErrorAction)).subscribe((error: any) => {
    this.notificationService.error(error.msg);
});