graycoreio/daffodil

View on GitHub
libs/geography/state/src/reducers/country-entities/country-entities.reducer.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { DaffCountry } from '@daffodil/geography';

import { getCountryAdapter } from './country-entities-adapter';
import { daffCountryEntitiesInitialState } from './country-entities-initial-state';
import { DaffCountryEntityState } from './country-entities-state.interface';
import {
  DaffGeographyActions,
  DaffGeographyActionTypes,
} from '../../actions/public_api';

/**
 * Reducer function that catches actions and changes/overwrites country entities state.
 */
export function daffCountryEntitiesReducer<T extends DaffCountry = DaffCountry>(
  state = daffCountryEntitiesInitialState,
  action: DaffGeographyActions<T>,
): DaffCountryEntityState<T> {
  const adapter = getCountryAdapter<T>();

  switch (action.type) {
    case DaffGeographyActionTypes.CountryLoadSuccessAction:
      return adapter.upsertOne({
        ...action.payload,
        loaded: true,
      }, state);

    case DaffGeographyActionTypes.CountryListSuccessAction:
      return adapter.upsertMany(
        action.payload.map(country => ({
          ...country,
          // defer to the loaded state of the country already in state (if it exists) but init field to false if it does not
          loaded: (state.entities[country.id] && state.entities[country.id].loaded) || false,
          // if the country coming in has no subdivisions and the same country in state does, use the subdivisions in state
          subdivisions: country.subdivisions.length === 0 && state.entities[country.id] && state.entities[country.id].subdivisions.length > 0
            ? state.entities[country.id].subdivisions
            : country.subdivisions,
        })),
        state,
      );

    default:
      return state;
  }
}