Skip to content

4.1.0: AJAX results.map(_normalizeItem) throws (undefined container) under ESM bundlers #6423

Description

@madejejej

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions