Skip to content

Document get_all_variants and get_all_variants_sync on the JS flags page - #257

Open
russell-loube-mixpanel wants to merge 7 commits into
mainfrom
docs/js-flags-get-all-variants
Open

russell-loube-mixpanel wants to merge 7 commits into
mainfrom
docs/js-flags-get-all-variants

Conversation

@russell-loube-mixpanel

Copy link
Copy Markdown
Contributor

What

Adds a Get All Flag Assignments section to the JavaScript (Web) feature flags page. get_all_variants() and get_all_variants_sync() have shipped in mixpanel-js since v2.79.0 and are in the public typings (FlagsManager), but appeared nowhere on the page.

Docs-only. No SDK changes, and the Swift page is untouched.

Structure

Mirrors the Swift page's equivalent section — same H3 placement under Flag Evaluation, same Synchronous/Asynchronous split — but the documented behavior is derived from src/flags/index.js, not from the Swift copy.

The JS-specific details it covers

  • Neither method fires exposure tracking. trackFeatureCheck has exactly one call site in the SDK (getVariantSync, src/flags/index.js:580); neither all-variants method reaches it, so no $experiment_started is sent. Pinned by a test at tests/unit/flags.js:1495. This is the main reason people reach for these methods, so it leads the section.
  • The return value is a Map, not a plain object. Swift's dictionary idiom doesn't translate and Object.keys(variants) silently yields []. Examples use .forEach((variant, key) => ...) and for...of.
  • No arguments and no fallback parameter, unlike get_variant — an unassigned flag is simply absent rather than falling back.
  • Per-policy async resolution (networkOnly / networkFirst / persistenceUntilNetworkSuccess), drawn from the tests at tests/unit/flags.js:1417, :1423, and :1436. The async method always resolves and never rejects.
  • One place JS genuinely diverges from Swift: the Swift docs say the async method "will attempt to fetch" if flags aren't loaded. JS does not — getAllVariants checks this.fetchPromise and returns an empty Map if nothing is in flight; it never calls loadFlags. Documented as the JS behavior.
  • Both return the SDK's internal Map by reference, not a copy (tests/unit/flags.js:1492 asserts strict identity). Mutating the result corrupts SDK flag state, so that gets a <Warning>.

Version claim

v2.79.0, established from the SDK repo rather than assumed. Both methods and their snake_case aliases landed together in c3a3e83 (mixpanel/mixpanel-js#433, "Implement flags variant persistence"); earliest tag containing it is v2.79.0; CHANGELOG 2.79.0 (14 May 2026) describes the persistence work; npm confirms 2.79.0 published 2026-05-14. Consistent with the version note already on the page's Flag Persistence section.

Left out, on purpose

get_variant_sync, are_flags_ready, load_flags, and when_ready also ship undocumented on this page. Kept out to keep this diff reviewable — happy to follow up in a separate PR.

Reviewer note

The ## Flag Evaluation preamble still says "This action triggers tracking an exposure event," which the new subsection contradicts locally. I left it alone because the Swift page has the same tension and resolves it in the subsection rather than the parent heading. Easy to soften if you'd rather.

🤖 Generated with Claude Code

Both methods ship in mixpanel-js v2.79.0 and are in the public typings,
but were absent from the JavaScript feature flags page. Mirrors the
structure of the Swift page's "Get All Flag Assignments" section, with
behavior derived from src/flags/index.js rather than from the Swift docs.

Covers the JS-specific details:
- Neither method routes through trackFeatureCheck, so neither fires
  $experiment_started exposure tracking.
- The return value is a Map, not a plain object, so Object.keys() yields
  an empty array. Examples use forEach and for...of.
- Both take no arguments and have no fallback parameter.
- Per-policy async resolution, and the fact that the async method awaits
  an in-flight fetch rather than starting one (unlike Swift).
- Both hand back the SDK's internal Map by reference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mintlify

mintlify Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
mixpanel-docs 🟢 Ready View Preview Oct 21, 2026, 10:43 PM

@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge, with one non-blocking clarification remaining in the copy advice.

Findings

  1. P2 Copied variants still share objects ▶

Reviews (7) · Last reviewed commit: "Merge branch 'main' into docs/js-flags-g..." · Reviewed by Greptile

Comment thread docs/tracking-methods/sdks/javascript/javascript-flags.mdx Outdated
Co-authored-by: efahk <37164746+efahk@users.noreply.github.com>
Comment thread docs/tracking-methods/sdks/javascript/javascript-flags.mdx Outdated
Each value is a full variant object, so [`variant_source`](#variant-source) and the rest of the variant metadata are available on every entry.

<Warning>
Both methods hand back the SDK's internal `Map` by reference, not a copy. Mutating the result corrupts the SDK's flag state — copy it first with `new Map(variants)` if you need to modify it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Copied variants still share objects

new Map(variants) copies the map, but not the variant objects inside it. A reader who follows this advice and changes copy.get(flagName).value still changes the SDK's flag state. Clarify that this copy only makes adding, deleting, or replacing map entries safe; changing variant objects requires copying those too.

Suggested change
Both methods hand back the SDK's internal `Map` by reference, not a copy. Mutating the result corrupts the SDK's flag state — copy it first with `new Map(variants)` if you need to modify it.
Both methods hand back the SDK's internal `Map` by reference, not a copy. Mutating the result corrupts the SDK's flag state. Use `new Map(variants)` before adding, deleting, or replacing map entries. This copy still shares the variant objects with the SDK, so copy those objects and any nested values you intend to change too.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@russell-loube-mixpanel what are your thoughts on this structuring suggestion?

This branch was successfully deployed

1 active deployment
staging — eef14e34 Deployed Oct 21, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants