Skip to content

Replace deprecated angular-instantsearch integration#63

Open
genson1808 wants to merge 2 commits into
BAWES-Universe:masterfrom
genson1808:genson/issue-32-instantsearch-upgrade
Open

Replace deprecated angular-instantsearch integration#63
genson1808 wants to merge 2 commits into
BAWES-Universe:masterfrom
genson1808:genson/issue-32-instantsearch-upgrade

Conversation

@genson1808

@genson1808 genson1808 commented May 15, 2026

Copy link
Copy Markdown

Summary

  • remove the deprecated angular-instantsearch dependency and add a local Angular compatibility wrapper backed by instantsearch.js
  • upgrade algoliasearch to v5 and update direct Algolia client calls to the v5 API
  • replace active ais-* Angular template tags with app-owned components while keeping existing candidate/fulltimer filter UI behavior

Verification

  • npm run build
  • rg "angular-instantsearch|NgAisModule|<ais-|</ais-|querystring-es3|algoliasearch-helper/src/version|initIndex" src package.json package-lock.json -n

/claim #32

Summary by CodeRabbit

Release Notes

  • Refactor
    • Migrated search and filtering infrastructure to use an updated Algolia search client and InstantSearch library. Search results, filters, refinements, and pagination functionality remain fully operational.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@genson1808 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 39 minutes and 52 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6838949c-8ca2-4e79-9f68-d3b2e1c22270

📥 Commits

Reviewing files that changed from the base of the PR and between 71edfe6 and 01d5368.

📒 Files selected for processing (3)
  • src/app/compat/instantsearch/highlight.component.ts
  • src/app/compat/instantsearch/instantsearch.component.ts
  • src/app/providers/logged-in/algolia.service.ts
📝 Walkthrough

Walkthrough

This PR migrates the application from the third-party angular-instantsearch library to a custom InstantSearch compatibility layer built on instantsearch.js and upgrades the algoliasearch client to v5. The migration involves creating wrapper components, updating all component imports and module dependencies, refactoring the Algolia service to use the v5 API, and updating page templates to use the new wrapper components.

Changes

Angular InstantSearch Migration to Custom Compatibility Layer

Layer / File(s) Summary
Dependencies and configuration scaffolding
package.json, tsconfig.json, src/app/compat/instantsearch/utils.ts, src/app/compat/instantsearch/index.ts
algoliasearch upgraded to ^5.52.1, angular-instantsearch removed, instantsearch.js added at ^4.97.0; TypeScript skipLibCheck enabled; utility functions (noop, parseNumberInput) and barrel exports established.
Compatibility layer base infrastructure
src/app/compat/instantsearch/base-widget.ts
BaseWidget abstract class provides lifecycle management, CSS class generation via bem() and cx(), widget state handling, and createWidget() factory; TypedBaseWidget<TWidgetDescription, TConnectorParams> refines state typing and options parameter.
InstantSearch wrapper components
src/app/compat/instantsearch/instantsearch.component.ts, src/app/compat/instantsearch/index-widget.component.ts, src/app/compat/instantsearch/infinite-hits.component.ts, src/app/compat/instantsearch/highlight.component.ts
NgAisInstantSearch wraps instantsearch.js with lifecycle and event emission; NgAisIndex manages index widgets; InstantSearchInfiniteHitsComponent provides pagination with show-more/show-previous; InstantSearchHighlightComponent renders highlighted search results.
Compatibility module and exports
src/app/compat/instantsearch/instantsearch.module.ts, src/app/compat/instantsearch/index.ts
InstantSearchCompatModule declares and exports all compat components; barrel index re-exports the public API.
Algolia client v5 API migration
src/app/providers/logged-in/algolia.service.ts
Import changed to named algoliasearch; search method replaced from client.initIndex(...).search(...) to client.searchSingleIndex(...) with searchParams construction; retry flow updated with same method.
Page-level client setup and component updates
src/app/pages/logged-in/candidate/candidate-search/candidate-search.page.ts, src/app/pages/logged-in/candidate/candidate-search/candidate-search.page.html, src/app/pages/logged-in/fulltimer/fulltimer-search/fulltimer-search.page.ts, src/app/pages/logged-in/fulltimer/fulltimer-search/fulltimer-search.page.html, src/app/pages/logged-in/candidate/candidate-search/candidate-search.module.ts, src/app/pages/logged-in/fulltimer/fulltimer-search/fulltimer-search.module.ts
Named import for algoliasearch; removed querystring-es3 encode setup; Algolia agent string changed to studenthub-staff-instantsearch; module imports updated to InstantSearchCompatModule; templates updated to use app-instantsearch and app-infinite-hits with bawes-ais-pagination for infinite scroll.
Component imports and module wiring
src/app/components/age-refinement-list/..., src/app/components/applied-filters/..., src/app/components/bawes-ais-pagination/..., src/app/components/candidate-filter/..., src/app/components/current-refinement/..., src/app/components/date-range-refinement-list/..., src/app/components/fulltimer-filter/..., src/app/components/is-facets-search/..., src/app/components/is-search-box/..., src/app/components/range-refinement-list/..., src/app/components/refinement-list/...
All component and module files updated to import BaseWidget, TypedBaseWidget, NgAisIndex, NgAisInstantSearch, parseNumberInput, and noop from src/app/compat/instantsearch; all feature modules updated to import and use InstantSearchCompatModule instead of NgAisModule.
Template and state format updates
src/app/components/refinement-list/refinement-list.component.html, src/app/components/age-refinement-list/age-refinement-list.component.ts, src/app/components/range-refinement-list/range-refinement-list.ts
Templates updated to replace ais-highlight with app-instantsearch-highlight; refinement list state format changed from noop function to explicit object with from and to formatter functions that stringify values.
Test spec file updates
src/app/components/applied-filters/applied-filters.component.spec.ts, src/app/components/current-refinement/current-refinement.component.spec.ts, src/app/components/is-facets-search/is-facets-search.component.spec.ts, src/app/components/is-search-box/is-search-box.component.spec.ts, src/app/components/refinement-list/refinement-list.component.spec.ts
Test imports updated to use NgAisInstantSearch from src/app/compat/instantsearch instead of angular-instantsearch.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Poem

🐰 From third-party bonds we hop away,
Building custom wrappers for our day,
Algolia v5 powers our new stride,
InstantSearch components, side by side,
A compatibility layer, strong and true—
Migrations made, the old shed for the new! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Replace deprecated angular-instantsearch integration' directly and clearly summarizes the main objective of the changeset - removing angular-instantsearch and implementing a local compatibility wrapper.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/providers/logged-in/algolia.service.ts (1)

93-119: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Retry branch completes too early and swallows errors.

Line 115 completes the observable before the retry searchSingleIndex resolves, so retry results can be dropped. Also, returning throwError(err) inside these promise callbacks does not notify this observer.

Proposed fix
-        }).catch(err => {
-
-          if(err.statusCode == 400) {
-            this.getKey(true).then(keyData => {
+        }).catch(err => {
+          if (err.statusCode === 400) {
+            this.getKey(true).then(keyData => {
 
               const client = algoliasearch(keyData.appId, keyData.securedApiKey, {});
 
               client.searchSingleIndex({
                 indexName,
                 searchParams: {
                   query: '',
                   ...searchParameters,
                 },
               }).then(content => {
-
-                if (content) {
-                  observer.next(content);
-                }
-              }).catch(err => {
-                  return throwError(err);
-              });
-
-              observer.complete();
-            });
+                observer.next(content);
+                observer.complete();
+              }).catch(retryErr => {
+                observer.error(retryErr);
+              });
+            }).catch(keyErr => observer.error(keyErr));
           } else {
-            return throwError(err);
+            observer.error(err);
           }
         });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/providers/logged-in/algolia.service.ts` around lines 93 - 119, The
retry branch currently calls observer.complete() immediately and uses return
throwError(err) inside promise callbacks which doesn't notify the Observable;
change the logic in the catch(err => { ... }) handling so that you only call
observer.complete() after client.searchSingleIndex(...).then(...) has resolved
and emitted (via observer.next(content)), and on any rejection from getKey or
searchSingleIndex call observer.error(err) (not return throwError(err)).
Specifically update the code paths around getKey(...).then(...) and
client.searchSingleIndex(...).then(...).catch(...) to propagate errors with
observer.error and to move observer.complete() into the final resolution of the
retry search so results are not dropped.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/compat/instantsearch/highlight.component.ts`:
- Around line 21-23: The getter content in HighlightComponent dereferences
this.hit._highlightResult without guarding this.hit; update the content getter
(the content accessor) to first check that this.hit is defined (or use optional
chaining) before calling getPropertyByPath on this.hit._highlightResult and on
this.hit, e.g. short-circuit to a safe default when this.hit is null/undefined
so getPropertyByPath is only invoked when this.hit exists and attribute is
present.

In `@src/app/compat/instantsearch/instantsearch.component.ts`:
- Line 12: The component currently ignores the `@Input`('index-name') indexName
and dereferences config.searchClient without guarding for null/undefined, which
can throw; update the component to use indexName (fallback to config.indexName
if needed) when constructing the InstantSearch instance and add null checks
before accessing config and config.searchClient (e.g. in ngOnInit or wherever
createInstantSearch is called) so you only call methods on searchClient when
config and config.searchClient are present, and return or no-op with a logged
warning if they are missing.

---

Outside diff comments:
In `@src/app/providers/logged-in/algolia.service.ts`:
- Around line 93-119: The retry branch currently calls observer.complete()
immediately and uses return throwError(err) inside promise callbacks which
doesn't notify the Observable; change the logic in the catch(err => { ... })
handling so that you only call observer.complete() after
client.searchSingleIndex(...).then(...) has resolved and emitted (via
observer.next(content)), and on any rejection from getKey or searchSingleIndex
call observer.error(err) (not return throwError(err)). Specifically update the
code paths around getKey(...).then(...) and
client.searchSingleIndex(...).then(...).catch(...) to propagate errors with
observer.error and to move observer.complete() into the final resolution of the
retry search so results are not dropped.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ede9bfaa-ebb6-421c-a7d1-617973b5f4ea

📥 Commits

Reviewing files that changed from the base of the PR and between 39a33ff and 71edfe6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (44)
  • package.json
  • src/app/compat/instantsearch/base-widget.ts
  • src/app/compat/instantsearch/highlight.component.ts
  • src/app/compat/instantsearch/index-widget.component.ts
  • src/app/compat/instantsearch/index.ts
  • src/app/compat/instantsearch/infinite-hits.component.ts
  • src/app/compat/instantsearch/instantsearch.component.ts
  • src/app/compat/instantsearch/instantsearch.module.ts
  • src/app/compat/instantsearch/utils.ts
  • src/app/components/age-refinement-list/age-refinement-list.component.ts
  • src/app/components/age-refinement-list/age-refinement-list.module.ts
  • src/app/components/applied-filters/applied-filters.component.spec.ts
  • src/app/components/applied-filters/applied-filters.component.ts
  • src/app/components/applied-filters/applied-filters.module.ts
  • src/app/components/bawes-ais-pagination/bawes-ais-pagination-module.module.ts
  • src/app/components/bawes-ais-pagination/bawes-ais-pagination.component.ts
  • src/app/components/candidate-filter/candidate-filter.module.ts
  • src/app/components/candidate-filter/candidate-filter.ts
  • src/app/components/current-refinement/current-refinement.component.spec.ts
  • src/app/components/current-refinement/current-refinement.component.ts
  • src/app/components/current-refinement/current-refinement.module.ts
  • src/app/components/date-range-refinement-list/date-range-refinement-list.component.ts
  • src/app/components/date-range-refinement-list/date-range-refinement-list.module.ts
  • src/app/components/fulltimer-filter/fulltimer-filter.module.ts
  • src/app/components/fulltimer-filter/fulltimer-filter.ts
  • src/app/components/is-facets-search/is-facets-search.component.spec.ts
  • src/app/components/is-facets-search/is-facets-search.module.ts
  • src/app/components/is-search-box/is-search-box.component.spec.ts
  • src/app/components/is-search-box/is-search-box.component.ts
  • src/app/components/is-search-box/is-search-box.module.ts
  • src/app/components/range-refinement-list/range-refinement-list.module.ts
  • src/app/components/range-refinement-list/range-refinement-list.ts
  • src/app/components/refinement-list/refinement-list.component.html
  • src/app/components/refinement-list/refinement-list.component.spec.ts
  • src/app/components/refinement-list/refinement-list.component.ts
  • src/app/components/refinement-list/refinement-list.module.ts
  • src/app/pages/logged-in/candidate/candidate-search/candidate-search.module.ts
  • src/app/pages/logged-in/candidate/candidate-search/candidate-search.page.html
  • src/app/pages/logged-in/candidate/candidate-search/candidate-search.page.ts
  • src/app/pages/logged-in/fulltimer/fulltimer-search/fulltimer-search.module.ts
  • src/app/pages/logged-in/fulltimer/fulltimer-search/fulltimer-search.page.html
  • src/app/pages/logged-in/fulltimer/fulltimer-search/fulltimer-search.page.ts
  • src/app/providers/logged-in/algolia.service.ts
  • tsconfig.json

Comment thread src/app/compat/instantsearch/highlight.component.ts
Comment thread src/app/compat/instantsearch/instantsearch.component.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant