title: Mithril - how to populate drop down list of view from API
body: <p>I'm trying to populate a drop down box rendered by Mithril's view from methods being called outside of its module (not sure if this terminology is correct, but outside of the property which contains the view, model and controller).</p>
  
  <p>This Chrome extension adds a new field to an existing page and depending on what the user select, the drop down box should refresh to items pertaining to the selected item. I can get up to the stage of getting the new list of items, but i cannot get the drop down list to redraw with the new objects.</p>
  
  <p>The following shows the module which gets inserted inside an existing page:</p>
  
  <pre><code>var ItemsList = {
    model: function () {
    this.list = function (id) {
       var d = m.deferred()
       // Calls Chrome extension bg page for retrieval of items.
       chromeExt.getItems(pId, function (items) {
         // Set default values initially when the controller is called.
         if (items.length === 0) {
           items = [
             {name: 'None', value: 'none'}
           ]
         }
         d.resolve(items || [])
       })
       return d.promise
     }
    },
  
    controller: function () {
      this.model = new ItemsList.model()
  
      this.index = m.prop(0)
  
      this.onchange = function (e) {
      console.info('ctrl:onchange', e.target)
      }
  
      // Initialise the drop down list array list.
      this.dropDownItemsList = m.prop([]);
  
      // This sets the default value of the drop down list to nothing by calling the function in the model, 
      // until the user selects an item which should populate the drop down list with some values.
      this.getItems = function(pId) {
        this.model.list(pId).then(function (data) {
        this.dropDownItemsList(data)
          m.redraw()
        }.bind(this))
      }
  
      this.getItems(0);
    },
  
    view: function (ctrl) {
      var SELECT_ID = 'record_select'
      return vm.Type() ? m('div', [
        m('.form__item', [
          m('.label', [
            m('label', {
              htmlFor: SELECT_ID
            }, 'ID')
          ]),
          m('.field', [
            m('select#' + SELECT_ID, {
                onchange: ctrl.onchange.bind(ctrl)
              },
              ctrl.dropDownItemsList().map(function (it, i) {
                return m('option', {
                  value: it.value,
                  checked: ctrl.model.index === i
                }, it.name)
              })
            ),
  
          ])
        ]),
      ]) : null
    }
  }
  </code></pre>
  
  <p>And it is mounted using 
  <code>m.mount("element name here", ItemsList);</code></p>
  
  <p>The code which checks to see if the item has changed is using a mutation observer, and whenever it detects changes to a certain field, it will call a method to get the new values. I can see that the return value has my new items.</p>
  
  <p>I have tried various different methods on trying to update the drop down list, first by trying to set the "this.list" with the new items list i've got, or trying to create a returnable method on the controller which i can call when the mutation observer fires.</p>
  
  <p>After getting the new items, how can i make the drop down list show the new items which has been retrieved? </p>
  
  <p>I have read guides which shows functions in the controller or model being run - but only if they've been defined to use them already in the view (i.e. have an onclick method on the view which calls the method) but so far i cannot figure out how to update or call methods from outside of the module.</p>
  
  <p>Is there a way to achieve the above or a different method i should approach this?</p>