LifeSports Application(ReactNative & Nest.js) - 15. map-service(3)

#1 maps 모듈

map-service에서 map 데이터를 불러오기 위한 5가지의 endpoint를 만들었습니다. 그 중 4가지 endpoint들은 맵 리스트를 불러오기 위한 REST API였고, maps 리덕스 모듈에선 이 API와 연동하여 맵 리스트를 state에 담을 수 있도록 구현하겠습니다.

  • ./src.lib/api/maps.js
import { takeLatest } from 'redux-saga/effects';
import { createAction, handleActions } from "redux-actions";
import createRequestSaga, { createRequestActionTypes } from "../lib/createRequestSaga";
import * as mapsAPI from '../lib/api/maps';

const [
    LIST_MAPS_ALL,
    LIST_MAPS_ALL_SUCCESS,
    LIST_MAPS_ALL_FAILURE,
] = createRequestActionTypes('maps/LIST_MAPS_ALL');

const [
    LIST_MAPS_TYPE,
    LIST_MAPS_TYPE_SUCCESS,
    LIST_MAPS_TYPE_FAILURE
] = createRequestActionTypes('maps/LIST_MAPS_TYPE');

const [
    LIST_MAPS_GU,
    LIST_MAPS_GU_SUCCESS,
    LIST_MAPS_GU_FAILURE
] = createRequestActionTypes('maps/LIST_MAPS_GU');

const [
    LIST_MAPS_GU_TYPE,
    LIST_MAPS_GU_TYPE_SUCCESS,
    LIST_MAPS_GU_TYPE_FAILURE
] = createRequestActionTypes('maps/LIST_MAPS_GU_TYPE');

export const listAll = createAction(LIST_MAPS_ALL);
export const listType = createAction(LIST_MAPS_TYPE, type_nm => type_nm);
export const listGu = createAction(LIST_MAPS_GU, gu_nm => gu_nm);
export const listGuType = createAction(LIST_MAPS_GU_TYPE, ({
    gu,
    type
}) => ({
    gu,
    type
}));

export const listAllSaga = createRequestSaga(LIST_MAPS_ALL, mapsAPI.getAll);
export const listTypeSaga = createRequestSaga(LIST_MAPS_TYPE, mapsAPI.getListByType);
export const listGuSaga = createRequestSaga(LIST_MAPS_GU, mapsAPI.getListByGu);
export const listGuTypeSaga = createRequestSaga(LIST_MAPS_GU_TYPE, mapsAPI.getListByGuType);

export function* mapsSaga() {
    yield takeLatest(LIST_MAPS_ALL, listAllSaga);
    yield takeLatest(LIST_MAPS_TYPE, listTypeSaga);
    yield takeLatest(LIST_MAPS_GU, listGuSaga);
    yield takeLatest(LIST_MAPS_GU_TYPE, listGuTypeSaga);
}

const initialState = {
    maps: null,
    error: null,
};

const maps = handleActions(
    {
        [LIST_MAPS_ALL_SUCCESS]: (state, { payload: maps }) => ({
            ...state,
            maps,
        }),
        [LIST_MAPS_ALL_FAILURE]: (state, { payload: error }) => ({
            ...state,
            error,
        }),
        [LIST_MAPS_TYPE_SUCCESS]: (state, { payload: maps }) => ({
            ...state,
            maps,
        }),
        [LIST_MAPS_TYPE_FAILURE]: (state, { payload: error }) => ({
            ...state,
            error,
        }),
        [LIST_MAPS_GU_SUCCESS]: (state, { payload: maps }) => ({
            ...state,
            maps,
        }),
        [LIST_MAPS_GU_FAILURE]: (state, { payload: error }) => ({
            ...state,
            error,
        }),
        [LIST_MAPS_GU_TYPE_SUCCESS]: (state, { payload: maps }) => ({
            ...state,
            maps,
        }),
        [LIST_MAPS_GU_TYPE_FAILURE]: (state, { payload: error }) => ({
            ...state,
            error,
        }),
    },
    initialState,
);

export default maps;
  • ./src/modules/index.js
import { combineReducers } from "redux";
import { all } from "redux-saga/effects";
import auth, { authSaga } from './auth';
import loading from "./loading";
import user, { userSaga } from "./user";
import marker from './marker';
import map from "./map";
import maps, { mapsSaga } from "./maps";

const rootReducer = combineReducers({
    auth,
    loading,
    user,
    marker,
    map,
    maps
});

export function* rootSaga() {
    yield all([
        authSaga(),
        userSaga(),
        mapsSaga(),
    ]);
};

export default rootReducer;

4개의 REST API를 위한 모듈을 생성했습니다. 4개의 API는 다음의 상황에서 쓰일 예정입니다.

1) listAllSaga: 맵 네비게이션에서 전체 데이터를 불러올 때 쓰입니다.

2) listTypeSaga: 홈 화면에서 운동별 카테고리로 분류되어있는 아이콘을 클릭하게 되면 쓰입니다.

3) listGuSaga: 추후에 만들 홈 화면에서의 지역별 카테고리를 클릭하게 되면 쓰입니다.

4) listGuTypeSaga: 맵 네비게이션에서 추후 생성할 1차, 2차 분류 탭에서 쓰입니다.

우선 1)의 기능부터 잘 수행되는지 확인해보도록 하겠습니다.

#2 maps 모듈 연동

http://localhost:1337로 들어가 wayfinding-service와 map-service도 API Gateway에 묶어주도록 하겠습니다.

  • ./src/pages/map/components/NaverMap.js
import React, { useEffect } from 'react';
import { StyleSheet } from 'react-native';
import NaverMapView from 'react-native-nmap';
import CustomMarker from './CustomMarker';
import { useDispatch, useSelector } from 'react-redux';
import { listAll } from '../../../modules/maps';

const NaverMap = () => {
    const { 
        visible,
        maps,
        error
    } = useSelector(({ 
        marker,
        maps,
    }) => ({ 
        visible: marker.visible,
        maps: maps.maps,
        error: maps.error,
    }));
    const dispatch = useDispatch();
    const defaultLocation = {
        latitude: 37.6009735, 
        longitude: 126.9484764
    };
    
    useEffect(() => {
        dispatch(listAll());

        if(error) {
            console.log(error)
        }
    }, [dispatch, error]);

    return(
        <NaverMapView style={ 
                          visible ? 
                          styles.openInfoContainer :
                          styles.closeInfoContainer
                      }
                      showsMyLocationButton={ true }
                      center={{
                          ...defaultLocation,
                          zoom: 15,
                      }}
                      scaleBar={ true }
        >
            {
                maps &&
                maps.map(
                    (map, i) => {
                        return <CustomMarker key={ i }
                                             data={ map } 
                               />
                    }
                )
            }
        </NaverMapView>
    );
};

const styles = StyleSheet.create({
    openInfoContainer: {
        width: '100%',
        height: '60%'
    },
    closeInfoContainer: {
        width: '100%',
        height: '90%',
    },
});

export default NaverMap;

NaverMap 렌더링 시 listAll 메서드를 호출하여 전체 데이터를 가져오도록 하겠습니다.

#3 maps 테스트

listAll메서드가 잘 호출이 된다면 maps state값에 맵 데이터들이 있어야 하므로 debugger를 확인해보겠습니다.

state값이 잘 있는 모습입니다.

state값을 가져와 map api위에 뿌려져 있는 모습입니다.

테스트 결과 맵 데이터들을 잘 가져오는 모습을 확인할 수 있습니다. 다음 포스트에서는 대관하기 상세페이지도 만들어 보도록 하겠습니다.

좋은 웹페이지 즐겨찾기