Actions must be plain objects. Use custom middleware for async actions.
nikiben opened this issue · 3 comments
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()] : []
)
}
}
@nikiben I think you're on the wrong repo. The angular 2+ ngRedux repository is here: https://github.com/angular-redux/store
He might be on wrong repo but same problems happens with ng-redux. I'm using ng-redux for angular 1.x. I've been on ^3.4.0-beta.1 for a long time and I updated yesterday to the newest one and I see "Actions must be plain objects" error. Getting rid of Redux Dev Tools Chrome makes it go away. For now, I just went back to 3.x. Here is my createStore code. Maybe I'm doing something obvious wrong but it's not documented.
$ngReduxProvider.createStoreWith(
reducer,
[
...someCustomMiddleware
'ngUiRouterMiddleware',
thunk,
],
window.__REDUX_DEVTOOLS_EXTENSION__
? [window.__REDUX_DEVTOOLS_EXTENSION__()]
: null,
{
...someState
}
);
@Pentiado I think the issue might be Redux Observable. Take a look at the link below. It might help. From the epic/effect function, I was dispatching an action inside an action instead of returning the action object.
https://stackoverflow.com/questions/48388594/angular-redux-epics