redux/track/sagas.ts

mail@pastecode.io avatar
unknown
plain_text
7 months ago
6.6 kB
1
Indexable
Never
import {put, takeEvery} from 'redux-saga/effects';

// GraphQL
import {getTrackData, getNearestTrackData} from '@graphql/queriesFn';

// Apollo
import apolloClient from '@ApolloClient/apolloClient';

// Utils
import {showErrorMessage} from '@Utils/toastMessage';
import {splitFullTrackIntoTrackSections} from '@Utils/splitFullTrackIntoTrackSections';

import * as Actions from './constants';

let callApiTime = 0;

/**
 * Fetch track data saga
 */

function* getNearestTrack({payload}) {
  yield put({type: Actions.TOGGLE_TRACK_LOADING, payload: true});
  try {
    const client = yield apolloClient();
    const res = yield client.query({
      query: getNearestTrackData(payload),
    });
    if (res && res.data) {
      yield put({
        type: Actions.GET_NEAREST_TRACK_SUCCESS,
        payload: res.data.nearest_track_data, // nearestCorridorData,
      });
    }
  } catch (e) {
    if (callApiTime < 3) {
      callApiTime += 1;
      yield getNearestTrack({payload});
      return;
    } else {
      callApiTime = 0;
      if (e?.errors) {
        if (e?.errors.length) {
          showErrorMessage(`Error 101: Could not get track data in Base mode`);
        } else {
          showErrorMessage(`Error 101: Could not get track data in Base mode`);
        }
      } else {
        showErrorMessage(
          'Error 101: Could not get track data from server in Base mode!',
        );
      }
    }
    yield put({type: Actions.GET_NEAREST_TRACK_FAIL});
  } finally {
    yield put({type: Actions.TOGGLE_TRACK_LOADING, payload: false});
  }
}

function* getAllTrackData({payload}) {
  yield put({type: Actions.TOGGLE_TRACK_LOADING, payload: true});
  const trackOrder = typeof payload.index !== 'undefined' ? payload.index : 0;
  try {
    const client = yield apolloClient();
    const res = yield client.query({
      query: getTrackData(payload),
    });
    if (res && res.data) {
      const fullTrackData = res.data.track_data.track_coordinates;
      const trackSections = splitFullTrackIntoTrackSections(
        fullTrackData,
        payload.stops,
      );

      // Offset each point in section by absolute start track distance
      const paddedTrackSections = trackSections.map(section => {
        console.log(section);
        return section.map(point => {
          return {
            ...point,
            dist_from_start_miles:
              point.dist_from_start_miles -
              section[0].absolute_track_distance_miles,
          };
        });
      });

      // Create track group payload for redux
      const trackGroupPayload = {};

      paddedTrackSections.forEach(section => {
        const trackStation = section
          .filter(
            item => item.station_name !== '' && item.station_name !== null,
          )
          .map((item: any) => {
            return {
              corridor: item.corridor,
              gpsCoordinates: {
                alt: item.gps_coordinates.alt,
                lat: item.gps_coordinates.lat,
                lng: item.gps_coordinates.lng,
              },
              id: item.station_name,
              name: item.station_name,
              type: 'STATION',
            };
          });

        const corridors = section.map((item: any) => {
          return {
            absoluteTrackDistanceMiles: item.absolute_track_distance_miles,
            corridor: item.corridor,
            distanceFromStart: item.dist_from_start_miles,
            distanceToNext: item.dist_to_next_miles,
            elevation: item.elevation,
            gpsCoordinates: {
              alt: item.gps_coordinates.alt,
              lat: item.gps_coordinates.lat,
              lng: item.gps_coordinates.lng,
            },
            grade: item.grade,
            milepost: item.milepost,
            station: item.station_name,
            stn1x: item.station_1,
            stn2x: item.station_2,
          };
        });

        const trackSpeedLimit = res.data.track_data.speed_limits.map(
          (item: any) => {
            return {
              endMile: item.end_mile,
              startMile: item.start_mile,
              startDistanceMiles: item.start_distance_miles,
              endDistanceMiles: item.end_distance_miles,
              value: item.speed_limit_mph,
            };
          },
        );

        const absoluteStartTrackDistanceMiles =
          corridors[0].absoluteTrackDistanceMiles;

        const trackData = {
          absoluteStartTrackDistanceMiles: absoluteStartTrackDistanceMiles,
          trackStation: trackStation,
          corridors: corridors,
          trackSpeedLimit: trackSpeedLimit,
        };

        const currentKey: string = `${corridors[0].stn1x}-${
          corridors[corridors.length - 1].stn1x
        }`;

        const trackGroup = {
          absoluteStartTrackDistanceMiles: absoluteStartTrackDistanceMiles,
          key: currentKey,
          data: trackData,
          order: trackOrder,
        };

        trackGroupPayload[currentKey] = trackGroup;
      });

      console.log('trackGroupPayload', trackGroupPayload);

      yield put({
        type: Actions.GET_TRACK_DATA_SUCCESS,
        payload: trackGroupPayload,
      });
    } else {
      if (callApiTime < 3) {
        callApiTime += 1;
        yield getAllTrackData({payload});
        return;
      } else {
        callApiTime = 0;
        showErrorMessage('Error 101: Could not get data from server!');
        yield put({
          type: Actions.GET_TRACK_DATA_FAIL,
          payload: {
            key: `${payload.start_destination_id}-${payload.end_destination_id}`,
            data: {},
            order: trackOrder,
          },
        });
      }
    }
  } catch (e) {
    if (callApiTime < 3) {
      callApiTime += 1;
      yield getAllTrackData({payload});
      return;
    } else {
      callApiTime = 0;
      if (e?.errors) {
        if (e?.errors.length) {
          showErrorMessage(`Error 101: Could not get track data`);
        } else {
          showErrorMessage(`Error 101: Could not get track data`);
        }
      } else {
        showErrorMessage('Error 101: Could not get track data from server!');
      }
    }
    yield put({
      type: Actions.GET_TRACK_DATA_FAIL,
      payload: {
        key: `${payload.start_destination_id}-${payload.end_destination_id}`,
        data: {},
        order: trackOrder,
      },
    });
  } finally {
    yield put({type: Actions.TOGGLE_TRACK_LOADING, payload: false});
  }
}

export default function* trackSaga() {
  yield takeEvery(Actions.GET_NEAREST_TRACK, getNearestTrack);
  yield takeEvery(Actions.GET_TRACK_DATA, getAllTrackData);
}