PawelC
PawelC

Reputation: 1216

My NgRx effects not working, nothing happend

I have problem with my NgRx effects.

The application correctly adds to the store, unfortunately my effects with the request are not performed, i.e. at the time of launching the addition of a new car, add it to the store and that's it. The problem is that there are no console logs from my effects, no http error because of the wrong url, nothing at all.

My app code:

Reducer

import { Action } from '@ngrx/store';
import * as CarActions from './car.actions';
import { Car } from 'src/models/car.model';

const initialState: Car = {
   brand: '',
   model: ''
};

export function carReducer(state: Car[] = [initialState], action: CarActions.Actions) {

    switch (action.type) {
        case CarActions.ADD_CAR:
            return [...state, action.payload];
        case CarActions.ADD_CAR_FAIL:
            return {
                ...state,
                carError: action.payload,
            };
        default:
            return state;
    }
}

State

import { Car } from './../../models/car.model';

export interface AppState {
  readonly car: Car;
}

Actions

import { Action } from '@ngrx/store';
import { Car } from './../../models/car.model';

export const ADD_CAR       = '[CAR] Add';
export const ADD_CAR_FAIL    = '[CAR] Fail';

export class AddCar implements Action {
    readonly type = ADD_CAR;

    constructor(public payload: Car) {}
}

export class AddCarFail implements Action {
    readonly type = ADD_CAR_FAIL;

    constructor(public payload: string) {}
}

export type Actions = AddCar | AddCarFail;

Effects

import { Actions, Effect, ofType } from '@ngrx/effects';
import * as CarActions from './car.actions';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { switchMap, catchError, map, tap } from 'rxjs/operators';
import { of } from 'rxjs';

@Injectable()
export class CarEffects {
    @Effect()
    carAdd = this.actions$.pipe(
        ofType(CarActions.ADD_CAR),
        switchMap((carData: CarActions.AddCar) => {
            console.log('true');
            return this.http.post('http://myapi.com/api', { brand: carData.payload.brand, model: carData.payload.model }).pipe(map(resData => {
                localStorage.setItem('test', 'asdasdasd');
            }),
                catchError(errorRes => {
                    console.log(errorRes);
                    const errorMessage = 'An unknown error occurred!';
                    if (!errorRes.error || !errorRes.error.error) {
                        return of(new CarActions.AddCarFail(errorMessage));
                    }

                    console.log(errorRes.error.error.message);
                    return of(new CarActions.AddCarFail(errorRes.error.error.message));
                }));
        })
    );

    constructor(
        private actions$: Actions,
        private http: HttpClient) { }
}

App.Module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { CarComponent } from './car/car.component';
import { StoreModule } from '@ngrx/store';
import { carReducer } from './car/car.reducer';
import { HttpClientModule } from '@angular/common/http';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';


@NgModule({
  declarations: [
    AppComponent,
    CarComponent
  ],
  imports: [
    BrowserModule,
    StoreModule.forRoot({ car: carReducer }),
    HttpClientModule,
    StoreDevtoolsModule.instrument({
      maxAge: 5
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

And most importantly, does my code use NgRx in a good way?

Upvotes: 4

Views: 3316

Answers (2)

Muhammad Ahsan Ayaz
Muhammad Ahsan Ayaz

Reputation: 1947

You need to import the EffectsModule to register your effects.

In the app.module.ts, you can do:

import {CarEffects} from 'path/to/careffects';

@NgModule({
  declarations: [
    AppComponent,
    CarComponent
  ],
  imports: [
    BrowserModule,
    StoreModule.forRoot({ car: carReducer }),
    HttpClientModule,
    StoreDevtoolsModule.instrument({
      maxAge: 5
    }),
    //                               ADD THIS BELOW !!
    EffectsModule.forRoot(
      [CarEffects]
    )
  ],
  providers: [],
  bootstrap: [AppComponent]
})

Upvotes: 2

Tony
Tony

Reputation: 20082

You did not add Effect to your module

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { CarComponent } from './car/car.component';
import { StoreModule } from '@ngrx/store';
import { carReducer } from './car/car.reducer';
import { HttpClientModule } from '@angular/common/http';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { EffectsModule } from '@ngrx/effects';
import { CarEffects } from './car/car.effects';


@NgModule({
  declarations: [
    AppComponent,
    CarComponent
  ],
  imports: [
    BrowserModule,
    StoreModule.forRoot({ car: carReducer }),
    HttpClientModule,
    EffectsModule.forRoot([CarEffects]),
    StoreDevtoolsModule.instrument({
      maxAge: 5
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Upvotes: 6

Related Questions