TypeScript is complaining that 'payload' does not exist on my type, even though it is clearly defined. Why is that so? Am I doing something wrong?
posts.action.ts
import { Action } from '@ngrx/store';
import { Post, NewPost } from '../../models/post.model';
.
.
.
export const CREATE_NEW_POST = '[Posts] Create New';
export const CREATE_NEW_POST_SUCCESS = '[Posts] Create New Success';
export const CREATE_NEW_POST_FAIL = '[Posts] Create New Fail';
export class CreateNewPost implements Action {
readonly type = CREATE_NEW_POST;
constructor(public payload: any) {}
}
export class CreateNewPostSuccess implements Action {
readonly type = CREATE_NEW_POST_SUCCESS;
constructor() {}
}
export class CreateNewPostFail implements Action {
readonly type = CREATE_NEW_POST_FAIL;
constructor(public payload: any) {}
}
// Post action types
export type PostAction =
| CreateNewPost
| FetchAllPosts
| FetchAllPostsSuccess
| FetchAllPostsFail
| AppendNewPost
| CreateNewPostSuccess
| CreateNewPostFail;
posts.effects.ts
@Effect()
createNewPost$ = this.actions$.ofType<allActions. PostAction>(allActions.CREATE_NEW_POST).pipe(
switchMap((action: allActions.PostAction) => {
return this.postService
.createPost(action.payload) // <--- THIS PAYLOAD DOES NOT EXIST? HOW?
.pipe(
map(postId => new allActions.CreateNewPostSuccess()),
catchError(error => of(new allActions.CreateNewPostFail(error)))
);
})
);
you have to cast type of action in ofType for now but it can be unnecessary when ts2.8 land
ofType<PostAction>(...)
I tried that too. Doesn't seem to get typescript from complaining.
can you share your screenshot?
@sandangel

I figured a workaround, but I don't like it very much.
In my posts.action.ts, for each action that does not need a payload I set the following constructor.
constructor(public payload: null) {}
This got TS to stop complaining about the payload not existing, but then now I have to pass a 'null' parameter whenever I dispatch an action for which I do not need to pass a payload, like so, .pipe(map(response => new allActions.CreateNewPostSuccess(null)));
I am not entirely convinced that this workaround is a solution. I have got to be overlooking something.
Thank you for taking a look at this issue though. Really appreciate it. 馃憤
@cyberbeast Hi, I think you probably do something wrong with your approach. I guess you are trying to handle the effect of CreateNewPost action, hence You should cast the ofType method with the CreateNewPost action instead of all PostAction.
That seems to work. But, I am exporting a type called PostsAction, like so,
// Post action types
export type PostAction =
| FetchAllPosts
| FetchAllPostsSuccess
| FetchAllPostsFail
| AppendNewPost
| CreateNewPost
| CreateNewPostSuccess
| CreateNewPostFail;
Shouldn't casting it to <PostAction> ideally mean the same.
Also, I am gonna mark this as the solution once I wrap my head around why the collection of actions as a single exported type doesn't work.
For those stumbling across this issue in the future, the solution lies in casting the ofType method to the specific action. @sandangel Thank you for suggesting this.
Take a look at the example app, they don't cast all Actions in 1 effects, but cast specific action for each. You should import * as PostActions from './actions'. This will increase some boilerplate for now but when ts2.8 land in Angular, you won't need cast type anymore. cheers ^^
Most helpful comment
@cyberbeast Hi, I think you probably do something wrong with your approach. I guess you are trying to handle the effect of CreateNewPost action, hence You should cast the ofType method with the CreateNewPost action instead of all PostAction.