Search code examples
javascriptjqueryhtmldomfirebase-realtime-database

TypeError: Cannot set property 'innerHTML' of null with a correct script location and div ID


I tried to figured out how I can fill up a <select> with brand names from my firebase table, but when my page loads innerHTML function found null

I have:

  • a correct place for my script - happens when my script is put in a OnLoad section in my .js or right before the </body>
  • a correct name for my div - since it's the most common case, I rename it with 3 letter, never used anywhere else in the document

for now I have this:

<fieldset class="inline-fields" id="inline-field1">
<div class = "row">
    <div class = "col-sm-4">
        <div class="form-group" id="select1">
            <select name="select-in" id="sel" class="form-control input-lg selectpicker" data-title="Marque" data-style="input-lg btn-default" data-live-search="true">
            <div id="selsel"></div>
            </select>
        </div>
    </div>
    <div class = "col-sm-8">
      <div class="row">
        <div class="col-sm-6">
          <input type="text" class="form-control form_after input-lg" id="form1" placeholder="Email"/>
        </div>
        <div class="col-sm-6">
          <input type="text" class="form-control form_after input-lg" id="form2" placeholder="Code Postal"/>
        </div>
      </div>
    </div>
</div></fieldset>

and I try to target the #selsel <div> in the #sel <select> but I paste the whole fieldset with bootstrap class for a more accurate information

here is the js:

            <script type="text/javascript">
            var html = "";
            firebase.database().ref('brand').on('value', function(snapshot) {
                var brand = snapshot.val();
                for (var i in brand) {
                    if (brand.hasOwnProperty(i) && typeof(i) !== 'function') {
                        elem = brand[i];
                        console.log(elem);
                        html += '<option>'
                        html += elem
                        html += '</option>'
                    }
                }
                document.getElementById('selsel').innerHTML = html;
            });
        </script>
    </body>

like you can see, right before body ends, it use firebase to gather data, at the end, my elem output look like this:
elem output screenshot

and my html output like this:
html output screenshot

another interesting thing is, when I put the #sel id in

document.getElementById('selsel').innerHTML = html;

instead of selsel (which is respectively the select#sel and the sub-div#selsel) I don't see the error but nothing populates the select


Solution

  • Simply you can't put div inside select, the browser won't render it. Running the snippet code you've provided and inspect element

    enter image description here

    Only allowed inside select <option> or <optgroup>.

    So just append <option> elements directly inside <select>, there is no point of adding them inside <div>, unless you want custom view of options that's another thing. And in that case you can use Select2 or bootstrap-select.

    Since you are using bootstrap why you don't use jQuery.

    <script type="text/javascript">
    $(document).ready(function(){
        var html = "";
        firebase.database().ref('brand').on('value', function(snapshot) {
            var brand = snapshot.val();
            for (var i in brand) {
                if (brand.hasOwnProperty(i) && typeof(i) !== 'function') {
                elem = brand[i];
                console.log(elem);
                html += '<option>'
                html += elem
                html += '</option>'
                }
            }
            $("#sel").html(html);
        }); 
    });
    </script>
    

    Edit 1

    Since you are using Bootstrap-select, first remove the class selectpicker from <select>

    <div class="form-group" id="select1">
        <select name="select-in" id="sel" class="form-control input-lg" data-title="Marque" data-style="input-lg btn-default" data-live-search="true">
        </select>
    </div>
    

    Then

    <script type="text/javascript">
        $(document).ready(function(){
            var html = "";
            firebase.database().ref('brand').on('value', function(snapshot) {
                var brand = snapshot.val();
                for (var i in brand) {
                    if (brand.hasOwnProperty(i) && typeof(i) !== 'function') {
                    elem = brand[i];
                    console.log(elem);
                    html += '<option>'
                    html += elem
                    html += '</option>'
                    }
                }
                $("#sel").html(html);
                $('#sel').selectpicker(); //you can pass options if you want
    
            }); 
        });
        </script>