Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

Angular NGRX with Star wars API

On this article we are going to create angular utility with ngrx and Star Wars API.To know what’s ngrx and the way we are able to you it with angular lets soar to ngrx documentation.

What’s NgRx?

NgRx is a framework for constructing reactive functions in Angular. NgRx gives libraries for:

  • Managing world and native state.
  • Isolation of uncomfortable side effects to advertise a cleaner element structure.
  • Entity assortment administration.
  • Integration with the Angular Router.
  • Developer tooling that enhances developer expertise when constructing many several types of functions.

Retailer

NgRx Retailer gives state administration for creating maintainable, express functions by way of using single state and actions to be able to categorical state adjustments. In circumstances the place you do not want a worldwide, application-wide answer to handle state, think about using NgRx ComponentStore which gives an answer for native state administration.

Impact

In a service-based Angular utility, parts are chargeable for interacting with exterior sources straight by way of companies. As an alternative, results present a option to work together with these companies and isolate them from the parts. Results are the place you deal with duties akin to fetching knowledge, long-running duties that produce a number of occasions, and different exterior interactions the place your parts do not want express information of those interactions.

Reducer

Generates a reducer file that comprises a state interface, an preliminary state object for the reducer, and a reducer perform.

Actions

Actions are one of many essential constructing blocks in NgRx. Actions categorical distinctive occasions that occur all through your utility. From consumer interplay with the web page, exterior interplay by way of community requests, and direct interplay with gadget APIs, these and extra occasions are described with actions.

Lets create our app, first you must create angular app you could find “get began” hyperlink here.For backend we are going to use SWAPI

Lets create reducer for our utility, first we are going to create folder “reducers” and inside we’d like create index.ts file.

import {
  ActionReducerMap,
  createFeatureSelector,
  createSelector,
  MetaReducer
} from '@ngrx/retailer';
import { surroundings } from '../../environments/surroundings';
import * as fromMovies from '../films/films.reducer';

export interface State {
  films: fromMovies.State;
}

export const reducers: ActionReducerMap<State> = {
  films: fromMovies.reducer,
};


export const metaReducers: MetaReducer<State>[] = !surroundings.manufacturing ? [] : [];

export const getMoviesState = createFeatureSelector<fromMovies.State>('films');
export const getMovies = createSelector(getMoviesState, state => state.knowledge);
export const getIsLoading = createSelector(getMoviesState, state => state.isLoading);
export const getMovieCharacters = createSelector(getMoviesState, state => state.selectedMovieCharacters);
export const getMovie = createSelector(getMoviesState, state => state.selectedMovie);
export const getCharacterMovies = createSelector(getMoviesState, state => state.selectedCharacterMovies);
export const getCharacter = createSelector(getMoviesState, state => state.selectedCharacter);

// export const getCurrentPage = createSelector(getMoviesState, state => state.web page);
// export const getIsFirstPage = createSelector(getMoviesState, state => !state.earlier);
// export const getIsLastPage = createSelector(getMoviesState, state => !state.subsequent);

Enter fullscreen mode

Exit fullscreen mode

and we are going to create characters and flicks parts inside app( you could find code from github),however on this article I wish to present ngrx half.Subsequent step is creating films.results.ts

import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/results';
import { Retailer } from '@ngrx/retailer';
// import { getCurrentPage } from '../reducers/index';
import { State } from './films.reducer';
import { MovieService } from './film.service';
import {
  MoviesActionTypes,
  MoviesActions,
  FetchMovies,
  FetchMoviesSuccess,
  FetchMoviesError,
  FetchMovieCharactersSuccess,
  FetchMovieCharactersError,
  FetchMovieError,
  FetchMovieSuccess,
  FetchCharacterError,
  FetchCharacterSuccess,
  FetchCharacterMoviesSuccess,
  FetchCharacterMoviesError
} from './films.actions';
import { Observable, of } from 'rxjs';
import { map, switchMap, catchError, withLatestFrom } from 'rxjs/operators';
import { CharactersService } from '../characters/characters.service';
import { Film } from './fashions/film';

@Injectable()
export class MoviesEffects {

  fetch$ = createEffect(() => {
    return this.actions$
      .pipe(
        ofType(MoviesActionTypes.FetchMovies),
        withLatestFrom(this.retailer),
        switchMap(([action, state]) =>
          this.service.getMovies().pipe(
            map(knowledge => new FetchMoviesSuccess(knowledge)),
            catchError(err => of(new FetchMoviesError(err)))
          )
        )
      )
  });
  fetchCharacters$ = createEffect(() => {
    return this.actions$
      .pipe(
        ofType(MoviesActionTypes.FetchMovieCharacters),
        withLatestFrom(this.retailer),
        switchMap(([action, state]) =>

          this.charactersService.getCharactersByFilm(this.service.selectedFilm).pipe(
            catchError(err => of(new FetchMovieCharactersError(err))),
            map(knowledge =>

              new FetchMovieCharactersSuccess(knowledge)
              // (characters: Film['charactersData']) => {
              // console.log("characters:", characters);
              // // this.movieService.selectedFilm.charactersData=[];
              // console.log("this.movieService.selectedFilm.charactersData:", this.movieService.selectedFilm.charactersData);


              // //  this.movieService.selectedFilm.charactersData = characters;
              // return true;
              // }
            )
          )
        ))
  });

  fetchCharacterMovies$ =  createEffect(() => {
    return this.actions$
      .pipe(
        ofType(MoviesActionTypes.FetchCharacterMovies),
        withLatestFrom(this.retailer),
        switchMap(([action, state]) =>

          this.service.getFilmsByCharacter(this.service.selectedCharacter).pipe(
            catchError(err => of(new FetchCharacterMoviesError(err))),
            map(knowledge =>

              new FetchCharacterMoviesSuccess(knowledge)
              // (characters: Film['charactersData']) => {
              // console.log("characters:", characters);
              // // this.movieService.selectedFilm.charactersData=[];
              // console.log("this.movieService.selectedFilm.charactersData:", this.movieService.selectedFilm.charactersData);


              // //  this.movieService.selectedFilm.charactersData = characters;
              // return true;
              // }
            )
          )
        ))
  });

  fetchMovie$ = createEffect(() => {
    return this.actions$
      .pipe(
        ofType(MoviesActionTypes.FetchMovie),
        withLatestFrom(this.retailer),
        switchMap(([action, state]) =>
          this.service.getFilm(this.service.selectedFilm.id).pipe(
            catchError(err => of(new FetchMovieError(err))),
            map(knowledge =>

              new FetchMovieSuccess(knowledge)
              // (characters: Film['charactersData']) => {
              // console.log("characters:", characters);
              // // this.movieService.selectedFilm.charactersData=[];
              // console.log("this.movieService.selectedFilm.charactersData:", this.movieService.selectedFilm.charactersData);


              // //  this.movieService.selectedFilm.charactersData = characters;
              // return true;
              // }
            )
          )
        ))
  });
  // this.service.getMovies().pipe(
  //   map(knowledge =>
  //     new FetchMovieCharactersSuccess(knowledge)
  //   ),
  //   catchError(err => of(new FetchMovieCharactersError(err)))
  // )
  //   )
  // );
  fetchCharacter$ = createEffect(() => {
    return this.actions$
      .pipe(
        ofType(MoviesActionTypes.FetchCharacter),
        withLatestFrom(this.retailer),
        switchMap(([action, state]) =>
          this.charactersService.getCharacter(this.service.selectedCharacter.id).pipe(
            catchError(err => of(new FetchCharacterError(err))),
            map(knowledge =>

              new FetchCharacterSuccess(knowledge)
            )
          )
        ))
  });
  paginate$ = createEffect(() => {
    return this.actions$
      .pipe(
        ofType(MoviesActionTypes.ChangePage),
        map(() => new FetchMovies())
      )
  });

  constructor(non-public actions$: Actions,
    non-public retailer: Retailer<State>,
    non-public service: MovieService,
    non-public charactersService: CharactersService) { }
}

Enter fullscreen mode

Exit fullscreen mode

we are going to use createEffect perform (Creates an impact from an Observable and an EffectConfig).

For film.reducer.ts we are going to use code under

import { Motion } from '@ngrx/retailer';
import { MoviesActions, MoviesActionTypes, Pagination } from './films.actions';
import { Film } from './fashions/film';
import { HttpErrorResponse } from '@angular/frequent/http';
import { Character } from '../characters/fashions/character';

export interface State  null;
  knowledge: Film[] 

export const initialState: State = {
  isLoading: false,
  error: null,
  knowledge: [],
  selectedMovieCharacters:[],
  selectedMovie: null,

  selectedCharacter: null,
  selectedCharacterMovies:[]


  // subsequent: null,
  // earlier: null,

};

export perform reducer(state = initialState, motion: MoviesActions): State {
  swap (motion.kind) {

    case MoviesActionTypes.FetchMovies:
      return {
        ...state,
        isLoading: true,
        error: null
      };

    case MoviesActionTypes.FetchMoviesSuccess:
      return {
        ...state,
        isLoading: false,
        knowledge: motion.payload,
        // subsequent: motion.payload.subsequent,
        // earlier: motion.payload.earlier
      };

    case MoviesActionTypes.FetchMoviesError:
      return {
        ...state,
        isLoading: false,
        error: motion.payload
      };
      case MoviesActionTypes.FetchMovie:
        return {
          ...state,
          isLoading: true,
          error: null
        };

      case MoviesActionTypes.FetchMovieSuccess:
        return {
          ...state,
          isLoading: false,
          selectedMovie: motion.payload,
          // subsequent: motion.payload.subsequent,
          // earlier: motion.payload.earlier
        };

      case MoviesActionTypes.FetchMovieError:
        return {
          ...state,
          isLoading: false,
          error: motion.payload
        };

    case MoviesActionTypes.FetchCharacter:
      return {
        ...state,
        isLoading: true,
        error: null
      };

    case MoviesActionTypes.FetchCharacterSuccess:
      return {
        ...state,
        isLoading: false,
        selectedCharacter: motion.payload,
        // subsequent: motion.payload.subsequent,
        // earlier: motion.payload.earlier
      };

    case MoviesActionTypes.FetchCharacterError:
      return {
        ...state,
        isLoading: false,
        error: motion.payload
      };

    case MoviesActionTypes.FetchCharacterMovies:
      return {
        ...state,
        isLoading: true,
        error: null
      };

    case MoviesActionTypes.FetchCharacterMoviesSuccess:
      return {
        ...state,
        isLoading: false,
        selectedCharacterMovies: motion.payload,
        // subsequent: motion.payload.subsequent,
        // earlier: motion.payload.earlier
      };

    case MoviesActionTypes.FetchCharacterMoviesError:
      return {
        ...state,
        isLoading: false,
        error: motion.payload
      };

    case MoviesActionTypes.FetchMovieCharacters:
      return {
        ...state,
        isLoading: true,
        error: null
      };

    case MoviesActionTypes.FetchMovieCharactersSuccess:
      return {
        ...state,
        isLoading: false,
        selectedMovieCharacters: motion.payload,
        // subsequent: motion.payload.subsequent,
        // earlier: motion.payload.earlier
      };


    case MoviesActionTypes.FetchMovieCharactersError:
      return {
        ...state,
        isLoading: false,
        error: motion.payload
      };

    // case MoviesActionTypes.ChangePage:
    //   return {
    //     ...state,
    //     web page: motion.payload === Pagination.NEXT ? ++state.web page : --state.web page
    //   };

    default:
      return state;
  }
}
Enter fullscreen mode

Exit fullscreen mode

we are going to create film.motion.ts

import { Motion } from '@ngrx/retailer';
import { Film, MoviesResponse } from './fashions/film';
import { HttpErrorResponse } from '@angular/frequent/http';

export const enum MoviesActionTypes {

  FetchMovies="[Movies] Fetch Films",
  FetchMoviesSuccess="[Movies] Load Films Success",
  FetchMoviesError="[Movies] Load Films Error",

  ChangePage="[Movies] Change web page",
  FetchMovieCharacters="[Movie] Fetch Film Characters",
  FetchMovieCharactersSuccess = `[Movie] Load Film Characters Success`,
  FetchMovieCharactersError="[Movie] Load Film Characters Error",
  FetchMovie="[Movie] Fetch Film ",
  FetchMovieSuccess = `[Movie] Load Film Success`,
  FetchMovieError="[Movie] Load Film Error",

  FetchCharacter="[Character] Fetch Character ",
  FetchCharacterSuccess = `[Character] Load Character Success`,
  FetchCharacterError="[Character] Load Character Error",

  FetchCharacterMovies="[Character] Fetch Character Films ",
  FetchCharacterMoviesSuccess = `[Character] Load Character Films Success`,
  FetchCharacterMoviesError="[Character] Load Character Films Error",

}

export const enum Pagination {
  NEXT,
  PREV
}

export class FetchMovies implements Motion {
  readonly kind = MoviesActionTypes.FetchMovies;
}

export class FetchMoviesSuccess implements Motion {
  readonly kind = MoviesActionTypes.FetchMoviesSuccess;

  constructor(public payload: Film[]) { }
}

export class FetchMoviesError implements Motion {
  readonly kind = MoviesActionTypes.FetchMoviesError;

  constructor(public payload: HttpErrorResponse) { }
}
export class FetchMovie implements Motion {
  readonly kind = MoviesActionTypes.FetchMovie;
  constructor() {
    // console.log("*************FetchMovie*************");

  }
}

export class FetchCharacterSuccess implements Motion {
  readonly kind = MoviesActionTypes.FetchCharacterSuccess;

  constructor(public payload: any) {
    // console.log("FetchMovieSuccess");

  }
}

export class FetchCharacterError implements Motion {
  readonly kind = MoviesActionTypes.FetchCharacterError;

  constructor(public payload: HttpErrorResponse) { }
}

export class FetchCharacter implements Motion {
  readonly kind = MoviesActionTypes.FetchCharacter;
  constructor() {
    // console.log("*************FetchCharacter*************");

  }
}
export class FetchCharacterMoviesSuccess implements Motion {
  readonly kind = MoviesActionTypes.FetchCharacterMoviesSuccess;

  constructor(public payload: any) {


  }
}

export class FetchCharacterMoviesError implements Motion {
  readonly kind = MoviesActionTypes.FetchCharacterMoviesError;

  constructor(public payload: HttpErrorResponse) { }
}

export class FetchCharacterMovies implements Motion {
  readonly kind = MoviesActionTypes.FetchCharacterMovies;
  constructor() {
    // console.log("*************FetchCharacter*************");

  }
}
export class FetchMovieSuccess implements Motion {
  readonly kind = MoviesActionTypes.FetchMovieSuccess;

  constructor(public payload: any) {
    // console.log("FetchMovieSuccess");

  }
}

export class FetchMovieError implements Motion {
  readonly kind = MoviesActionTypes.FetchMovieError;

  constructor(public payload: HttpErrorResponse) { }
}

export class FetchMovieCharacters implements Motion {
  readonly kind = MoviesActionTypes.FetchMovieCharacters;
}

export class FetchMovieCharactersSuccess implements Motion {
  readonly kind = MoviesActionTypes.FetchMovieCharactersSuccess;


  constructor(public payload: any) {
    // console.log("FetchMovieCharactersSuccess");
  }
}

export class FetchMovieCharactersError implements Motion {
  readonly kind = MoviesActionTypes.FetchMovieCharactersError;

  constructor(public payload: HttpErrorResponse) { }
}



export class ChangePage implements Motion {
  readonly kind = MoviesActionTypes.ChangePage;

  constructor(public payload: Pagination) { }
}

export kind MoviesActions = FetchMovieCharacters
  | FetchMovieCharactersSuccess
  | FetchMovieCharactersError
  | FetchMovies
  | FetchMoviesSuccess
  | FetchMoviesError
  | FetchMovie
  | FetchMovieSuccess
  | FetchMovieError
  | FetchCharacter
  | FetchCharacterSuccess
  | FetchCharacterError
  | FetchCharacterMovies
  | FetchCharacterMoviesSuccess
  | FetchCharacterMoviesError
  | ChangePage;

Enter fullscreen mode

Exit fullscreen mode

For movie-list element , movie-detail element and different character parts you could find full mission on this github link.
Once you run mission you possibly can see record of “star wars” films

Image description

After clicking to film in record app exhibits films particulars and record of characters

Image description

By clicking character identify app will navigate to character particulars web page, and it’ll present character particulars and record of films the place character exist.

Image description

and you’ll click on film identify and it’ll navigate to film particulars web page.Utility makes use of ngrx state to working all course of with films and characters.

Hope, this text provide help to to know ngrx.

Add a Comment

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?