My approach w/ this has been similar to @user1337, but w/ a bit more type enforcement:
redux-actions/appointment.ts
import { Action } from '@ngrx/store';
export enum ActionTypes {
SetStartTime = 'Set Start Time',
SetEndTime = 'Set End Time'
}
interface SetStartTime extends Action {
readonly type: ActionTypes;
readonly startTime: Date;
}
interface SetEndTime extends Action {
readonly type: ActionTypes;
readonly endTime: Date;
}
export interface AppointmentActions extends
SetStartTime,
SetEndTime {}
export function setStartTime(startTime: Date): SetStartTime {
return {
type: ActionTypes.SetStartTime,
startTime
};
}
export function setEndTime(endTime: Date): SetEndTime {
return {
type: ActionTypes.SetStartTime,
endTime
};
}
reducers/appointment.ts
import { ActionTypes, AppointmentActions } from '../redux-actions/appointment.ts';
interface AppointmentState {
startTime: Date;
endTime: Date;
}
export const initialState: AppointmentState = {
startTime: null,
endTime: null
};
export function appointmentReducer(state = initialState, action: AppointmentActions): AppointmentState {
switch (action.type) {
case ActionTypes.SetStartTime:
return {
...state,
startTime: action.startTime
};
case ActionTypes.SetEndTime:
return {
...state,
endTime: action.endTime
};
default:
return state;
}
}
This solution makes it so that you now have type enforcement and intellisense available in both the reducer as well as the redux action.
So, now to dispatch the redux action:
appointment.component.ts
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { appointmentReducer as appointment } from '../reducers/appointment';
import { setStartTime, setEndTime } from '../redux-actions/appointment';
@Component({
selector: 'app-appointment-component',
templateUrl: './appointment.component.html',
styleUrls: ['./appointment.component.css'],
})
export class AppointmentComponent {
....
constructor(private store: Store<{ appointment }>) {
...
}
setStartTime(startTime: Date) {
this.store.dispatch(setStartTime(startTime);
}
}