[TIL] 카테고리 필터 만들어 주기

Lea·2020년 6월 16일
0

2020-06-13~14 개발일지👩‍💻

지난번에 DB에서 불러온 위도/경도로 지도에 마커 표시하는 것까지는 성공했고, 다음 작업은 카테고리 필터를 선택했을 때 해당 카테고리에 맞는 장소만 마커로 표시하는 것!

원래 기획 단계에서는 초기 지도에 전체 장소를 먼저 보여주고, 사용자가 필터를 선택하면 해당 장소만 보여주는 형태로 생각했는데 그럼 첫 화면에서 보이는 지도가 다소 산만할 것 같다는 생각이 들었다. 그래서 아무 장소도 표시되지 않은 초기 지도 상태에서 필터를 누르고 버튼을 클릭하면 원하는 장소만 보여주도록 약간 수정했다!

카테고리 필터는 어떤 식으로 만들어야 하는지, 감이 안 잡혀서 수업시간에 튜터님한테 여쭤보며 아이디어를 얻었고 대략 이런 구조로 만들었다.

Step 01. 카테고리 체크박스에서 선택된 값만 리스트로 모으기

     //체크박스 리스트 생성
      var check_count = document.getElementsByName("category").length;
      var check_box_list = []
      for (let i = 0; i < check_count; i++) {
        if (document.getElementsByName("category")[i].checked == true) {
          check_box_list.push(document.getElementsByName("category")[i].value)
        }
      }

Step 02. 서버에게 API로 값을 보내줄 때, url에 '?filter=선택된 체크박스1, 선택된 체크박스2' 이런 형태로 붙여서 보내주기

      //url 생성
      url = '/places?filter='
      for (let i = 0; i < check_box_list.length; i++) {
        if (i != 0) {
          url = url + ',' + check_box_list[i];
        } else {
          url = url + check_box_list[i];
        }
      }
      $.ajax({
        type: 'GET',
        url: url,
        data: {},
        success: function (response) {
          if (response['result'] == 'success') {
            let bakerys = response['bakerys_list']
            for (let i = 0; i < bakerys.length; i++) {
              var bakery = { lat: bakerys[i]['latitude'], lng: bakerys[i]['longitude'] }
              var marker = new google.maps.Marker({ position: bakery, map: map, title: bakerys[i]['name'] });
            }
          }
        }
      });

Step 03. 서버에서 프론트로부터 받은 url의 filter 값 split으로 개별 요소로 잘라주기
Step 04. split으로 잘라준 값들을 DB 불러올 때 조건에 넣어주기

import json

def remove_dupe_dicts(l):
    return [dict(t) for t in {tuple(d.items()) for d in l}]
    
@app.route('/places', methods=['GET'])
def bakery_list():
    filter = request.args.get('filter')
    filter_list = filter.split(',')
    bakerys = []
    for category in filter_list:
        bakery = list(db.bakery.find({category: True}, {'_id': False}))
        bakerys.extend(bakery)
    # 리스트에 중복된 딕셔너리 제거
    bakerys_list = remove_dupe_dicts(bakerys)
    return jsonify({'result': 'success', 'bakerys_list': bakerys_list})    

최대한 배운 선에서 만들려다보니까 다소 조잡한 느낌인 건 기분탓일까...😅 그리고 사실은 원래 split한 필터값들을 OR 조건으로 필터에 한 번에 넣어서 db를 한 번만 불러오게 하려했는데, 뭔가 잘 안풀렸다. 그래서 그냥 필터값별로 조건을 걸어서 반복문으로 리스트에 쌓고, 중복된 장소들은 삭제해주는 형태로 방법을 바꿨다. 아마 이 방법 말고 더 간단한 방법이 있을 것 같은데, 나중에 다시 찾아봐야겠다.

결과적으로는 어찌저찌 필터 적용하는데 성공했고, 이제는 마커를 눌렀을 때 모달이 뜨는 이벤트를 적용해야 한다. 다시 구글맵 API의 늪으로.. 빠져보자...

profile
마케터로서 혼자 고민하고, 공부하고, 기록합니다.

0개의 댓글