フリマアプリのカテゴリー実装のエラー解決

### 前提・実現したいこと

プログラミングスクールのチーム開発でフリマアプリを製作中です。
カテゴリー機能実装でエラーが出たので、それをどのように解決したかを記録することにしました。

### 発生している問題・エラー(YouTube動画)
エラー画面をYouTubeにアップしました。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/myXNj39feWA/0.jpg)](http://www.youtube.com/watch?v=myXNj39feWA)
QiitaにはYouTubeの埋め込みはできないみたいなので、画像をクリックして動画に飛んで見てください。

![FURIMAカテゴリ実装エラー解決記事1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/77b5fe16-ea8a-a8e2-addf-07fa604a2216.png)

親カテゴリーを選択すると子カテゴリーが出てきて、子カテゴリーを選択すると孫カテゴリーが出てくる設定になっています。

問題なのは、上記の画像の状態からもう一度親カテゴリーを選び直すと、また下に子カテゴリーが出てきてしまうことです。

![FURIMAカテゴリ実装エラー画面2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/3efdfa0d-422f-b3aa-f4f1-0a54ef485e60.png)
親カテゴリーを選び直したら、下の画面のようになって欲しいのです。

![FURIMAカテゴリ実装エラー解決記事3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/95992bf3-07ed-6e2e-be18-c170b3482490.png)

### エラー画面のソースコード

```javascript:category.js
(省略)
$(window).on('load',function(){
  if(document.URL.match('new')) {
    $('#parent_category').on('change', function(){
      var parentCategory = $(this).val();  
        if (parentCategory != "---"){
          $.ajax({ 
            url: 'get_category_children', 
            type: 'GET',              
            data: { parent_id: parentCategory },  
            dataType: 'json' 
            }) 
            .done(function(children){ 
              $('#children_wrapper').remove();  
              $('#grandchildren_wrapper').remove(); 
              var insertHTML = ''; 
              children.forEach(function(child){ 
                insertHTML += appendOption(child); 
              }); 
              appendChidrenBox(insertHTML); 
             }) 
             .fail(function(){ 
               alert('カテゴリー取得に失敗しました'); 
             }) 
         } else { 
           $('#children_wrapper').remove();  
           $('#grandchildren_wrapper').remove(); 
         } 
       }); 
       $('.category-section__pulldown').on('change', '#child_category', function(){ 
         var childId = $('#child_category option:selected').data('category');  
         if (childId != "---"){  
           $.ajax({ 
             url: 'get_category_grandchildren', 
             type: 'GET', 
             data: { child_id: childId },  
             dataType: 'json' 
           }) 
           .done(function(grandchildren){ 
             if (grandchildren.length != 0) { 
               $('#grandchildren_wrapper').remove();  
               var insertHTML = ''; 
               grandchildren.forEach(function(grandchild){ 
                 insertHTML += appendOption(grandchild); 
               }); 
               appendGrandchidrenBox(insertHTML); 
              } 
            }) 
            .fail(function(){ 
              alert('カテゴリー取得に失敗しました'); 
            }) 
          } else { 
            $('#grandchildren_wrapper').remove();  
          } 
        }); 
(省略)
```

### 解決後のソースコード

```javascript:category.js
$(window).on('load',function(){
    if(document.URL.match('new')) {
      $('#parent_category').on('change', function(){
        var parentCategory = $(this).val(); 
        if ($('div').hasClass('category-select-child')){ 
          $('.category-select-child').remove();
          $('.category-select-grandchild').remove();
          $.ajax({
            url: 'get_category_children',
            type: 'GET',
            data: { parent_id: parentCategory }, 
            dataType: 'json'
          })
          .done(function(children){
            var insertHTML = '';
            children.forEach(function(child){
              insertHTML += appendOption(child);
            });
            appendChidrenBox(insertHTML);
          })
          .fail(function(){
            alert('カテゴリー取得に失敗しました');
          })
        } else {
          $.ajax({
            url: 'get_category_children',
            type: 'GET',
            data: { parent_id: parentCategory }, 
            dataType: 'json'
          })
          .done(function(children){
            var insertHTML = '';
            children.forEach(function(child){
              insertHTML += appendOption(child);
            });
            appendChidrenBox(insertHTML);
          })
          .fail(function(){
            alert('カテゴリー取得に失敗しました');
          })
        }
      });
```

### 解決方法
以下のように条件分岐の設定を変えました。

```javascript:エラーの場合
var parentCategory = $(this).val();  
  //親カテゴリーのidが入っている場合＝親カテゴリーの情報が入った場合
  if (parentCategory != "---"){
　  //ajaxで子カテゴリーの情報を受け取りjson形式で返す
　  //子カテゴリーを追加
  } else {
    //(省略)ここの記述間違えてて何の意味もなかった
  }
```
親カテゴリーが選択されて情報が入っているかいないかで条件分岐されていたところを、
子カテゴリーがあるかないかで条件分岐することにしました。

```javascript:解決後の場合
//子カテゴリーのクラスがある場合
if ($('div').hasClass('category-select-child')){
  //子カテゴリーを消す
  $('.category-select-child').remove();
  //ajaxの処理
  //新たに子カテゴリーを追加
} else {
//子カテゴリーのクラスがない場合
  //単純に子カテゴリーを追加
}
```
`.hasClass`メソッドは、そのクラスがあるかないかを判定して、trueかfalseで返してくれます。

子カテゴリーがあれば、まず既存の子カテゴリーをremoveメソッドで消してから新たに子カテゴリーを追加し、
子カテゴリーがなければ、単純に今まで通り子カテゴリーを追加するだけにしました。

### 解決後の挙動(YouTube動画)
解決後の挙動の動画をYouTubeにアップしました。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/1KvC5QKxO-s/0.jpg)](http://www.youtube.com/watch?v=1KvC5QKxO-s)
※QiitaにはYouTubeの埋め込みはできないみたいなので、画像をクリックして動画に飛んで見てください。

### 補足情報
ruby 2.5.1
Rails 5.2.4.3

### 参考記事
[【jQuery入門】hasClass()でクラスの存在有無を調べる方法！](https://www.sejuku.net/blog/54940)