1

How do I send a payload when dispatching an action in angular-redux? I can't find it anywhere explained, neither in the official tutorials, nor in the API-Docs.

The class 'Action' has a property 'type', but no property 'payload'.

API-Docs: https://angular-redux.github.io/store/

user1337
  • 460
  • 6
  • 22

2 Answers2

0

What I did now is instead of creating actions of type Action I created actions of type AnyAction.

AnyAction extends Action and has an additional property 'extraProps':

export interface AnyAction extends Action {
  // Allows any extra properties to be defined in an action.
  [extraProps: string]: any;
}

So that I can now add the payload to my action declaration:

myAction(payload: any): AnyAction {
    return { type: MyActions.MY_ACTION, extraProps: payload };
}

And now I can call dispatch with the payload as a parameter:

this.ngRedux.dispatch(this.myActions.myAction(payload));

And use it in my store:

case MyActions.MY_ACTION: {
    // payload
    let payload = action['extraProps'];
}

But is this the right way to send payload with an action in angular-redux?

user1337
  • 460
  • 6
  • 22
0

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);
  }
}
TheScrappyDev
  • 4,375
  • 2
  • 21
  • 25