Summary
Select2 4.1.0 throws when loading AJAX results:
TypeError: Cannot read properties of undefined (reading 'container')
at SelectAdapter._normalizeItem (…)
The results dropdown stays on “Searching…” and never renders options.
This does not occur on 4.0.13 (that release does not normalize AJAX results in ajax.js).
Cause
#6241 added AJAX result normalization in src/js/select2/data/ajax.js:
results.results = results.results.map(
AjaxAdapter.prototype._normalizeItem
);
SelectAdapter.prototype._normalizeItem uses this.container (and this.generateResultId). Passing the method unbound to Array#map leaves this as undefined when _normalizeItem is a strict-mode function (typical after ESM bundling with Vite/Webpack/Rollup).
#6239 added the same unbound pattern for optgroup children in select.js.
Reproduction
Minimal Vite repro (recommended): https://gist.github.com/madejejej/8c73bc3159e097027447a10616a52284
# clone gist files into vite-repro/ or download from gist
cd vite-repro
npm install
npm run build && npm run preview
# open http://127.0.0.1:4173
Expected output in <pre id="log">:
direct normalize(): Cannot read properties of undefined (reading 'container')
Array#map(unbound): Cannot read properties of undefined (reading 'container')
Upstream diff: 4.0.13 → 4.1.0 only adds the results.results.map(…_normalizeItem) block in ajax.js (plus Array.isArray / abort guard tweaks).
Note: Loading select2.full.min.js via a classic non-module <script> may mask the bug (sloppy this / window). Modern apps import select2 as an npm package through bundlers.
Suggested fix
Bind the adapter instance in AjaxAdapter.prototype.query:
results.results = results.results.map(function (item) {
return self._normalizeItem(item);
});
Mirror for optgroup children in _normalizeItem:
item.children = item.children.map(function (child) {
return this._normalizeItem(child);
}, this);
Context
Proposed test
See proposed-ajax-tests.js in the gist for a QUnit case that exercises AjaxAdapter#query with a synchronous transport.
Summary
Select2 4.1.0 throws when loading AJAX results:
The results dropdown stays on “Searching…” and never renders options.
This does not occur on 4.0.13 (that release does not normalize AJAX
resultsinajax.js).Cause
#6241 added AJAX result normalization in
src/js/select2/data/ajax.js:SelectAdapter.prototype._normalizeItemusesthis.container(andthis.generateResultId). Passing the method unbound toArray#mapleavesthisasundefinedwhen_normalizeItemis a strict-mode function (typical after ESM bundling with Vite/Webpack/Rollup).#6239 added the same unbound pattern for optgroup
childreninselect.js.Reproduction
Minimal Vite repro (recommended): https://gist.github.com/madejejej/8c73bc3159e097027447a10616a52284
Expected output in
<pre id="log">:Upstream diff: 4.0.13 → 4.1.0 only adds the
results.results.map(…_normalizeItem)block inajax.js(plusArray.isArray/ abort guard tweaks).Note: Loading
select2.full.min.jsvia a classic non-module<script>may mask the bug (sloppythis/window). Modern apps importselect2as an npm package through bundlers.Suggested fix
Bind the adapter instance in
AjaxAdapter.prototype.query:Mirror for optgroup children in
_normalizeItem:Context
Proposed test
See
proposed-ajax-tests.jsin the gist for a QUnit case that exercisesAjaxAdapter#querywith a synchronoustransport.