Skip to content

Conversation

@vicb
Copy link
Owner

@vicb vicb commented Jan 3, 2026

Summary by Sourcery

Bug Fixes:

  • Fix Google Maps loading to explicitly import the maps, marker, and geometry libraries instead of relying on the deprecated libraries option.

Summary by CodeRabbit

Release Notes

  • Refactor
    • Enhanced map loading performance through concurrent library initialization.

✏️ Tip: You can customize this high-level summary in your review settings.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 3, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates Google Maps loading to explicitly import maps, marker, and geometry libraries via Promise.all instead of using the deprecated libraries option on the loader, ensuring all required libraries are loaded before resolving.

Sequence diagram for updated Google Maps library loading

sequenceDiagram
  participant Component
  participant loadGMaps
  participant GMapLoader

  Component->>loadGMaps: loadGMaps()
  activate loadGMaps
  loadGMaps->>GMapLoader: setOptions(key, v)
  loadGMaps->>GMapLoader: importLibrary(maps)
  loadGMaps->>GMapLoader: importLibrary(marker)
  loadGMaps->>GMapLoader: importLibrary(geometry)
  GMapLoader-->>loadGMaps: Promise.all resolved
  loadGMaps-->>Component: gMapsApiLoading Promise resolved
  deactivate loadGMaps
Loading

File-Level Changes

Change Details Files
Ensure required Google Maps libraries (maps, marker, geometry) are explicitly imported and fully loaded before the map API is considered ready.
  • Remove use of the loader options libraries array when configuring Google Maps JS API loader.
  • Change the loader flow to call importLibrary for maps, marker, and geometry explicitly.
  • Wrap the three importLibrary calls in Promise.all and only resolve the shared gMapsApiLoading promise after all have completed.
apps/fxc-front/src/app/components/2d/map-element.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Jan 3, 2026

Walkthrough

Refactored Google Maps library initialization in map-element.ts to load maps, marker, and geometry libraries concurrently using Promise.all() instead of sequentially. The change removes the previous libraries: ['geometry', 'marker'] option and single importLibrary('maps') then-chain pattern, replacing it with parallel importLibrary calls that resolve when all complete.

Changes

Cohort / File(s) Summary
Google Maps Library Loading
apps/fxc-front/src/app/components/2d/map-element.ts
Replaced sequential importLibrary('maps') with concurrent loading of maps, marker, and geometry libraries via Promise.all([importLibrary('maps'), importLibrary('marker'), importLibrary('geometry')]). Removed libraries array configuration option. Maintains existing load sequencing and state handling logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • Remove FFVL delay #282: Modifies the same map-element.ts file and Google Maps loading flow, removing an artificial FFVL delay around loadGMaps.

Poem

🐰 Three libraries hop in at once,
No waiting in the queue!
Parallel paths through the maps so vast—
Swift loading, shiny new.
Geometry and markers dance together,
Promise.all knows what to do! 🗺️

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: fixing the loading mechanism of Google Maps libraries by switching to parallel Promise.all loading instead of sequential imports.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch vicb/load-gmap-libs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The new Promise.all([...]).then(() => resolve()) chain doesn’t handle rejections; consider propagating failures (e.g., using catch or async/await with try/catch) so callers can distinguish load errors from success.
  • You can simplify the then callback by passing resolve directly (...).then(resolve) instead of wrapping it in an arrow function with an explicit void return type.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `Promise.all([...]).then(() => resolve())` chain doesn’t handle rejections; consider propagating failures (e.g., using `catch` or `async/await` with `try/catch`) so callers can distinguish load errors from success.
- You can simplify the `then` callback by passing `resolve` directly (`...).then(resolve)` instead of wrapping it in an arrow function with an explicit `void` return type.

## Individual Comments

### Comment 1
<location> `apps/fxc-front/src/app/components/2d/map-element.ts:57-61` </location>
<code_context>
-        libraries: ['geometry', 'marker'],
       });
-      gMapLoader.importLibrary('maps').then(() => resolve());
+      Promise.all([
+        gMapLoader.importLibrary('maps'),
+        gMapLoader.importLibrary('marker'),
+        gMapLoader.importLibrary('geometry'),
+      ]).then((): void => {
+        resolve();
+      });
</code_context>

<issue_to_address>
**issue (bug_risk):** Promise.all lacks rejection handling, which can leave gMapsApiLoading unresolved on failure

If any library fails to load, the outer promise never settles and callers can hang indefinitely. Please either propagate rejection (e.g., expose `reject` and use `.then(resolve, reject)`), or attach a `.catch` that resolves or rejects `gMapsApiLoading` with a clear failure state.
</issue_to_address>

### Comment 2
<location> `apps/fxc-front/src/app/components/2d/map-element.ts:61-62` </location>
<code_context>
+        gMapLoader.importLibrary('maps'),
+        gMapLoader.importLibrary('marker'),
+        gMapLoader.importLibrary('geometry'),
+      ]).then((): void => {
+        resolve();
+      });
     };
</code_context>

<issue_to_address>
**suggestion:** The extra Promise wrapper and explicit resolve in `.then` could be simplified

Since `gMapsApiLoading` already reflects the loader’s resolution, you can simplify this to `.then(resolve)` instead of wrapping `resolve` in a function. You might also be able to return `Promise.all` directly from `loadGMaps` and drop the extra `new Promise` if no other code relies on holding an external `resolve` reference.

Suggested implementation:

```typescript
      Promise.all([
        gMapLoader.importLibrary('maps'),
        gMapLoader.importLibrary('marker'),
        gMapLoader.importLibrary('geometry'),
      ]).then(resolve);

```

To fully apply the second part of your suggestion (dropping the extra `new Promise` and external `resolve`), you’ll need to:

1. Change the code that sets `gMapsApiLoading` to directly use the `Promise.all` chain (or a function that returns that chain), for example:
   - Replace `gMapsApiLoading = new Promise((r) => (resolve = r));` with something like:
     `gMapsApiLoading = Promise.all([...imports...]).then(() => undefined);`
2. Remove the `let resolve: () => void = () => null;` declaration and any other uses of `resolve` tied to this pattern.
3. Ensure that any callers that depend on `gMapsApiLoading` being a `Promise<void>` still work correctly (you may need to map the `Promise.all` result to `void` with `.then(() => undefined)` if the type matters).

These refactors depend on the surrounding context (how `gMapsApiLoading` and `resolve` are used elsewhere), so they should be adjusted to match the rest of the file.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +61 to +62
]).then((): void => {
resolve();
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: The extra Promise wrapper and explicit resolve in .then could be simplified

Since gMapsApiLoading already reflects the loader’s resolution, you can simplify this to .then(resolve) instead of wrapping resolve in a function. You might also be able to return Promise.all directly from loadGMaps and drop the extra new Promise if no other code relies on holding an external resolve reference.

Suggested implementation:

      Promise.all([
        gMapLoader.importLibrary('maps'),
        gMapLoader.importLibrary('marker'),
        gMapLoader.importLibrary('geometry'),
      ]).then(resolve);

To fully apply the second part of your suggestion (dropping the extra new Promise and external resolve), you’ll need to:

  1. Change the code that sets gMapsApiLoading to directly use the Promise.all chain (or a function that returns that chain), for example:
    • Replace gMapsApiLoading = new Promise((r) => (resolve = r)); with something like:
      gMapsApiLoading = Promise.all([...imports...]).then(() => undefined);
  2. Remove the let resolve: () => void = () => null; declaration and any other uses of resolve tied to this pattern.
  3. Ensure that any callers that depend on gMapsApiLoading being a Promise<void> still work correctly (you may need to map the Promise.all result to void with .then(() => undefined) if the type matters).

These refactors depend on the surrounding context (how gMapsApiLoading and resolve are used elsewhere), so they should be adjusted to match the rest of the file.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23da754 and 7cdaa94.

📒 Files selected for processing (1)
  • apps/fxc-front/src/app/components/2d/map-element.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Sourcery review
  • GitHub Check: build (22.x)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Cloudflare Pages

Comment on lines +57 to +63
Promise.all([
gMapLoader.importLibrary('maps'),
gMapLoader.importLibrary('marker'),
gMapLoader.importLibrary('geometry'),
]).then((): void => {
resolve();
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

head -100 apps/fxc-front/src/app/components/2d/map-element.ts | cat -n

Repository: vicb/flyXC

Length of output: 4082


🏁 Script executed:

sed -n '40,80p' apps/fxc-front/src/app/components/2d/map-element.ts | cat -n

Repository: vicb/flyXC

Length of output: 1544


🏁 Script executed:

rg -n "gMapsApiLoading" apps/fxc-front/src/app/components/2d/map-element.ts -A 2 -B 2

Repository: vicb/flyXC

Length of output: 705


🏁 Script executed:

rg "@googlemaps/js-api-loader" --type json

Repository: vicb/flyXC

Length of output: 358


🏁 Script executed:

rg -n "loadGMaps" apps/fxc-front/src/app/components/2d/map-element.ts -B 2 -A 2

Repository: vicb/flyXC

Length of output: 371


🌐 Web query:

@googlemaps/js-api-loader version 2.0.2 importLibrary supported library names

💡 Result:

Supported importLibrary names (as of the Maps JS API / js-api-loader v2.x docs):

  • core
  • maps
  • maps3d
  • places
  • geocoding
  • routes
  • marker
  • geometry
  • elevation
  • streetview
  • journeysharing
  • drawing
  • visualization

Sources: Google Maps JS API top-level reference and Libraries guide. [1][2]

References
[1] Google Maps JavaScript API — google.maps (top-level reference).
[2] Google Maps JavaScript API — Libraries (dynamic importLibrary guide).


🏁 Script executed:

sed -n '46,81p' apps/fxc-front/src/app/components/2d/map-element.ts | cat -n

Repository: vicb/flyXC

Length of output: 1386


Add error handling to prevent app hang on library load failure.

The parallel loading approach is efficient and correct. However, if any of the importLibrary calls fails (e.g., network error, invalid API key, quota limits), the Promise.all() will reject and resolve() will never be called. This leaves gMapsApiLoading in a pending state indefinitely, causing the app to hang at the splash screen (where loadGMaps() is awaited on line 155).

Proposed fix to add error handling
 Promise.all([
   gMapLoader.importLibrary('maps'),
   gMapLoader.importLibrary('marker'),
   gMapLoader.importLibrary('geometry'),
-]).then((): void => {
-  resolve();
-});
+])
+  .then((): void => {
+    resolve();
+  })
+  .catch((error) => {
+    console.error('Failed to load Google Maps libraries:', error);
+    resolve(); // Or handle the error appropriately
+  });

All three library names ('maps', 'marker', 'geometry') are supported in @googlemaps/js-api-loader v2.0.2.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Promise.all([
gMapLoader.importLibrary('maps'),
gMapLoader.importLibrary('marker'),
gMapLoader.importLibrary('geometry'),
]).then((): void => {
resolve();
});
Promise.all([
gMapLoader.importLibrary('maps'),
gMapLoader.importLibrary('marker'),
gMapLoader.importLibrary('geometry'),
])
.then((): void => {
resolve();
})
.catch((error) => {
console.error('Failed to load Google Maps libraries:', error);
resolve(); // Or handle the error appropriately
});
🤖 Prompt for AI Agents
In apps/fxc-front/src/app/components/2d/map-element.ts around lines 57-63, the
Promise.all(...) call currently only handles the success path and never handles
rejection, which can leave gMapsApiLoading pending and hang the app; add error
handling by attaching a .catch handler to the Promise.all that logs the error
and rejects the surrounding promise (or otherwise resolves with a failure state)
so callers don't wait indefinitely; ensure the surrounding Promise executor
calls either resolve() on success or reject(err) on failure and include a clear
log message with the error details to aid debugging.

@vicb vicb merged commit 5d54128 into master Jan 3, 2026
7 checks passed
@vicb vicb deleted the vicb/load-gmap-libs branch January 3, 2026 17:47
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.

2 participants