Skip to content

Commit c477b6f

Browse files
tkirda-bisonclaude
andcommitted
docs: fix transformResult example, which never worked as written
Browser-verified the local dist/ build against jQuery 4 and found the readme's non-standard-payload example is broken: the default dataType is "text", so $.ajax hands transformResult the raw response STRING and `response.myData` is undefined. The built-in transformResult copes by JSON.parse-ing string input, but a custom one replaces that — so the documented snippet silently yields zero suggestions (or throws, depending how the callback indexes the payload). This is the same example that issue #891 was filed against; widening the parameter type made it compile, which would have made a non-working snippet type-check cleanly. - readme: add `dataType: 'json'` to both snippets and explain the string-vs-object distinction, with the JSON.parse alternative. - test: cover the dataType: "json" path — asserts transformResult gets a parsed object and maps a non-standard payload. The existing spec covers the default "text" path (it calls result.split(",")), so both are now pinned. 42 specs pass. - docs/index.htm: version stamp said 2.0.2 while npm is on 2.0.5; bump it and add a release-flow step so it stops drifting. Verified in Chrome: local UMD, minified UMD and ESM bundles all register and work on jQuery 4.0.0 (grouping, ghost hint, keyboard and mouse selection, data round-trip, mockjax ajax lookup), and the live demo runs the published 2.0.5 from jsDelivr on jQuery 3.7.1. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X29RAqzWDUD7UptThtJZGv
1 parent 85f8bd2 commit c477b6f

4 files changed

Lines changed: 78 additions & 6 deletions

File tree

‎CLAUDE.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ The minified UMD is ~13 KB; the unminified is ~26 KB.
6161
1. Bump `version` in `package.json`.
6262
2. `npm install --package-lock-only` — keeps the lockfile's own `version` field in step. Easy to forget; 2.0.5 shipped with a lockfile still claiming 2.0.4 (harmless — `npm ci` doesn't validate it and the tarball excludes it — but it drifts).
6363
3. `npm run build` — propagates the new version into the banner of each `dist/` JS file (via the build script) and syncs `devbridge-autocomplete.jquery.json`.
64-
4. Commit as `chore(release): <version>`, then tag `v<version>` and push the tag — `.github/workflows/release.yml` fires on `v*`, re-runs the full CI sweep, publishes to npm with provenance (OIDC, no token), and opens the GitHub Release. Registry propagation lags the workflow by a minute or two, so `npm view` can still report the previous version right after a green run — confirm against `https://registry.npmjs.org/devbridge-autocomplete` before assuming the publish failed.
64+
4. Update the version stamp in `docs/index.htm` (the `stamp__big` / `stamp__line3` spans, around line 33) — it's hand-maintained and visible on the live demo, so it drifts silently. It sat at 2.0.2 while npm was on 2.0.5.
65+
5. Commit as `chore(release): <version>`, then tag `v<version>` and push the tag — `.github/workflows/release.yml` fires on `v*`, re-runs the full CI sweep, publishes to npm with provenance (OIDC, no token), and opens the GitHub Release. Registry propagation lags the workflow by a minute or two, so `npm view` can still report the previous version right after a green run — confirm against `https://registry.npmjs.org/devbridge-autocomplete` before assuming the publish failed.
6566

6667
## Updating dependencies
6768

‎docs/index.htm‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ <h1 class="lockup">
3030
</div>
3131
<aside class="stamp" aria-hidden="true">
3232
<span class="stamp__line1">Version</span>
33-
<span class="stamp__big">2.0.2</span>
34-
<span class="stamp__line3">May &middot; 2026</span>
33+
<span class="stamp__big">2.0.5</span>
34+
<span class="stamp__line3">Sep &middot; 2026</span>
3535
</aside>
3636
</header>
3737

‎readme.md‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ non-standard payload, use `paramName` and `transformResult`:
245245
```js
246246
$('#autocomplete').autocomplete({
247247
paramName: 'searchString',
248+
dataType: 'json',
248249
transformResult: function (response) {
249250
return {
250251
suggestions: response.myData.map((item) => ({
@@ -256,16 +257,30 @@ $('#autocomplete').autocomplete({
256257
});
257258
```
258259

259-
`transformResult` receives the raw payload `$.ajax` resolved with, so its
260-
type is up to your service. In TypeScript you can annotate the parameter
261-
with your own response shape:
260+
**`dataType: 'json'` matters here.** `transformResult` receives whatever
261+
`$.ajax` resolved with, and the default `dataType` is `'text'` — so
262+
without it your callback is handed the raw response **string**, and
263+
`response.myData` is `undefined`. (The built-in `transformResult` copes by
264+
running `JSON.parse` on string input; a custom one replaces that.) Either
265+
set `dataType: 'json'` and let jQuery parse, or parse it yourself:
266+
267+
```js
268+
transformResult: function (response) {
269+
const parsed = typeof response === 'string' ? JSON.parse(response) : response;
270+
return { suggestions: parsed.myData.map(/* … */) };
271+
}
272+
```
273+
274+
In TypeScript the parameter is typed loosely, since only your service
275+
knows the payload shape — annotate it with your own type:
262276

263277
```ts
264278
interface MyResponse {
265279
myData: { valueField: string; dataField: number }[];
266280
}
267281

268282
$('#autocomplete').autocomplete({
283+
dataType: 'json',
269284
transformResult: (response: MyResponse) => ({
270285
suggestions: response.myData.map((item) => ({
271286
value: item.valueField,

‎test/autocomplete.test.js‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,62 @@ describe("Autocomplete Async — transformResult", () => {
168168
});
169169
});
170170

171+
// The default dataType is "text", so a custom transformResult is handed the raw
172+
// response string. With dataType: "json" jQuery parses first and the callback
173+
// sees an object — the form the readme documents for non-standard payloads.
174+
describe("Autocomplete Async — transformResult with dataType json", () => {
175+
let instance;
176+
let receivedType;
177+
178+
beforeEach(async () => {
179+
await new Promise((resolve) => {
180+
const input = document.createElement("input");
181+
const url = "/test-transform-json";
182+
const autocomplete = new $.Autocomplete(input, {
183+
serviceUrl: url,
184+
dataType: "json",
185+
transformResult: function (response) {
186+
receivedType = typeof response;
187+
setTimeout(resolve, 0);
188+
189+
return {
190+
suggestions: response.myData.map(function (item) {
191+
return { value: item.valueField, data: item.dataField };
192+
}),
193+
};
194+
},
195+
});
196+
197+
$.mockjax({
198+
url,
199+
responseTime: 50,
200+
contentType: "application/json",
201+
responseText: {
202+
myData: [
203+
{ valueField: "Canada", dataField: "CA" },
204+
{ valueField: "Cameroon", dataField: "CM" },
205+
],
206+
},
207+
});
208+
209+
instance = autocomplete;
210+
211+
input.value = "C";
212+
autocomplete.onValueChange();
213+
});
214+
});
215+
216+
it("Should hand transformResult a parsed object", () => {
217+
expect(receivedType).toBe("object");
218+
});
219+
220+
it("Should map a non-standard payload onto suggestions", () => {
221+
expect(instance.suggestions.length).toBe(2);
222+
expect(instance.suggestions[0].value).toBe("Canada");
223+
expect(instance.suggestions[0].data).toBe("CA");
224+
});
225+
});
226+
171227
describe("Autocomplete Async — optional server query field", () => {
172228
let instance;
173229

0 commit comments

Comments
 (0)