Skip to content

Actions must be plain objects. Use custom middleware for async actions. #188

Open
@nikiben

Description

@nikiben

Getting the following error message in console when using the angular-redux library. Also, Redux won't catch or listen for actions after the error occurs. I've searched, including the documentation but nothing points out to fix the error. Am I missing something?

Error

core.js:1427 ERROR Error: Actions must be plain objects. Use custom middleware for async actions.
    at Object.performAction (<anonymous>:3:2312)
    at liftAction (<anonymous>:2:27846)
    at dispatch (<anonymous>:2:31884)
    at eval (createEpicMiddleware.js:67)
    at SafeSubscriber.dispatch [as _next] (applyMiddleware.js:35)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
    at SafeSubscriber.next (Subscriber.js:187)
    at Subscriber._next (Subscriber.js:128)
    at Subscriber.next (Subscriber.js:92)
    at SwitchMapSubscriber.notifyNext (switchMap.js:127)

Component

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { select } from '@angular-redux/store';
import { ScheduleActions } from '../store/actions'

@Component({
  selector: 'app-page2',
  templateUrl: './page2.component.html',
  styleUrls: ['./page2.component.css']
})
export class Page2Component implements OnInit {

  @select(['schedule', 'scheduleList']) values: any;
  values: any;
  constructor(public actions: ScheduleActions) { }

  ngOnInit() {
	this.actions.loadSchedule();
  }
}

Actions

//schedule-actions.ts
import { Injectable } from '@angular/core';
import { NgRedux } from '@angular-redux/store';
import { Schedule } from '../../model/schedule.model';

@Injectable()
export class ScheduleActions {
    static readonly LOAD_SCHEDULE = 'LOAD_SCHEDULE';
    static readonly LOAD_SCHEDULE_SUCCESS = 'LOAD_SCHEDULE_SUCCESS';

    constructor(private ngRedux: NgRedux<any>){}

    loadSchedule(){
        this.ngRedux.dispatch({
            type: ScheduleActions.LOAD_SCHEDULE
        });
    }
}

Reducer

//schedule-reducer.ts
import { ScheduleActions } from '../actions';

export interface SCHEDULE_STATE {
    scheduleList: any,
    scheduleDetail: any
}

const initialState: SCHEDULE_STATE = {
    scheduleList: [],
    scheduleDetail: {}
}

export const ScheduleReducer = (state: SCHEDULE_STATE = initialState, action): SCHEDULE_STATE => {
    switch(action.type){
        case ScheduleActions.LOAD_SCHEDULE_SUCCESS:
            return {...state, scheduleList: action.payload };
        case ScheduleActions.LOAD_SCHEDULE_DETAIL_SUCCESS:
            return {...state, scheduleList: action.payload };
        case ScheduleActions.CREATE_SCHEDULE_SUCCESS:
            return {...state, scheduleDetail: action.payload };
        default:
            return state;
    }
}

Epics

//schedule-epic.ts
import { Injectable } from '@angular/core';
import { ActionsObservable, ofType } from 'redux-observable';
import { ScheduleService } from '../services';
import { ScheduleActions } from '../actions';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class ScheduleEpic {
    constructor(private service: ScheduleService, 
        private actions: ScheduleActions
    ){}

    loadScheduleEpic = (action$: ActionsObservable<any>) => {
        return action$.ofType(ScheduleActions.LOAD_SCHEDULE)
        .mergeMap(action => {
            return this.service.loadSchedule().map(result => {
                this.actions.loadScheduleSuccess(result)
            })

        })
    }
}

Service

//schedule-service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Schedule } from '../../model/schedule.model';

@Injectable()
export class ScheduleService {

    private API_URL: String = "http://mockserver.io/v2";

    constructor(private http: HttpClient){}

    loadSchedule(){
        return this.http.get(this.API_URL + '/5a6225153100004f2bde7f27').map(res => res)
    }
}

And off course the setup

.......imports......
.......@NgModule.........
export class AppModule { 
	constructor(
		private ngRedux: NgRedux<any>,
		private rootEpic: RootEpic,
		private devTools: DevToolsExtension
	){
		this.ngRedux.configureStore(
			rootReducer,
			INITIAL_STATE,
			[createEpicMiddleware(rootEpic.createEpics())],
			devTools.isEnabled() ? [devTools.enhancer()] : []
		)
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions