<p dir="auto">When a typeahead <code class="notranslate">process</code> call receives an array of objects instead of strings it passes "[Object object]" to <a href="https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js#L54"><code class="notranslate">updater</code></a>. One would expect that updater would receive the object, as <code class="notranslate">matcher</code>, <code class="notranslate">sorter</code>, and <code class="notranslate">highlighter</code> work as expected.</p>
<p dir="auto">The problem seems to be that the data is being stored by way of calls to jQuery.attr.</p>
<p dir="auto">One potential fix is changing <a href="https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js#L47">https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js#L47</a> and <a href="https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js#L141">https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js#L141</a> respectively as follows:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="47       var val = this.$menu.find('.active').attr('data-value')"><pre class="notranslate"><code class="notranslate">47       var val = this.$menu.find('.active').attr('data-value')
</code></pre></div>
<p dir="auto">becomes</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="47       var val = this.$menu.find('.active').data('typeahead-value')"><pre class="notranslate"><code class="notranslate">47       var val = this.$menu.find('.active').data('typeahead-value')
</code></pre></div>
<p dir="auto">and</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="141        i = $(that.options.item).attr('data-value', item)"><pre class="notranslate"><code class="notranslate">141        i = $(that.options.item).attr('data-value', item)
</code></pre></div>
<p dir="auto">becomes</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" 141       i = $(that.options.item).data('typeahead-value', item)"><pre class="notranslate"><code class="notranslate"> 141       i = $(that.options.item).data('typeahead-value', item)
</code></pre></div>
<p dir="auto">The underlying issue is jQuery's <a href="http://api.jquery.com/attr/" rel="nofollow">'attr'</a> function calls <code class="notranslate">toString</code> instead of serializing, whereas <a href="http://api.jquery.com/jQuery.data/" rel="nofollow">'data'</a> serializes properly - preserving all the useful bits of the object.</p>
<p dir="auto">Note that I changed 'data-value' to 'typeahead-value' just to avoid any name collisions (although I am sure they are pretty unlikely).</p>
<p dir="auto">A workaround is to serialize with eg <code class="notranslate">JSON.stringify</code> the results of <code class="notranslate">sorter</code>, and then <code class="notranslate">JSON.parse</code> the item passed to <code class="notranslate">updater</code>.</p>
<p dir="auto">your current set up is so:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=".clearfix() {
  &amp;:before,
  &amp;:after {
    content: &quot; &quot;; // 1
    display: table; // 2
  }
  &amp;:after {
    clear: both;
  }
}

.clearfix {
  .clearfix();
}"><pre class="notranslate"><code class="notranslate">.clearfix() {
  &amp;:before,
  &amp;:after {
    content: " "; // 1
    display: table; // 2
  }
  &amp;:after {
    clear: both;
  }
}

.clearfix {
  .clearfix();
}
</code></pre></div>
<p dir="auto">consider switching to this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=".clearfix {
  &amp;:before,
  &amp;:after {
    content: &quot; &quot;; // 1
    display: table; // 2
  }
  &amp;:after {
    clear: both;
  }
}

.clearfix() {
  &amp;:extend(.clearfix all);
}"><pre class="notranslate"><code class="notranslate">.clearfix {
  &amp;:before,
  &amp;:after {
    content: " "; // 1
    display: table; // 2
  }
  &amp;:after {
    clear: both;
  }
}

.clearfix() {
  &amp;:extend(.clearfix all);
}
</code></pre></div>
<p dir="auto">it will reduce the amount of resulting css when devs use your mixin in their own less files. There will still be some duplicate with .clearfix() calling both mixin .clearfix() and selector .clearfix (known issue with less.js, and I do wish you would change .clearfix() to .makeclearfix() or .addclearfix() or whatever to alleviate this problem, but I know you won't).</p>
<p dir="auto">When the good fellas over at LESS do fix that problem, this code (combined with my suggested change)</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=".my-class {
  .clearfix();
}"><pre class="notranslate"><code class="notranslate">.my-class {
  .clearfix();
}
</code></pre></div>
<p dir="auto">will result in:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=".clearfix:before,
.clearfix:after,
.my-class:before,
.my-class:after {
  content: &quot; &quot;;
  display: table;
}
.clearfix:after,
.my-class:after {
  clear: both;
}
.my-class {
  color: blue;
}"><pre class="notranslate"><code class="notranslate">.clearfix:before,
.clearfix:after,
.my-class:before,
.my-class:after {
  content: " ";
  display: table;
}
.clearfix:after,
.my-class:after {
  clear: both;
}
.my-class {
  color: blue;
}
</code></pre></div>
<p dir="auto">and of course if a dev uses .clearfix(); throught their own less files, the resultant compiled css will see a pretty significant reduction in size</p>