Skip to content

Conversation

@jmcbroom
Copy link
Collaborator

@jmcbroom jmcbroom commented Jul 16, 2025

a very rough start -- more or less taking code from the existing address-autocomplete.

some questions/thoughts i have:

  • i'm assuming we just want the input in the autocomplete box, and not as a separate component?
  • should this fetch/hit find as the user enters text with some kind of debounce/min length before fetching? or should it wait until Enter is hit?

@netlify
Copy link

netlify bot commented Jul 16, 2025

Deploy Preview for oslmap ready!

Name Link
🔨 Latest commit d58ba61
🔍 Latest deploy log https://app.netlify.com/projects/oslmap/deploys/6892c70fb53eb50008e495b5
😎 Deploy Preview https://deploy-preview-562--oslmap.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@jmcbroom jmcbroom marked this pull request as ready for review July 21, 2025 09:22
Copy link
Member

@jessicamcinchak jessicamcinchak left a comment

Choose a reason for hiding this comment

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

This works exactly as a I expect! Welcome to geo web component land 🌟

A few minor comments below - think "option" display is the big one to address before merging, but very close to ready !

@jmcbroom
Copy link
Collaborator Author

thanks for the review @jessicamcinchak -- i think this should be good to go now!

Copy link
Contributor

@DafyddLlyr DafyddLlyr left a comment

Choose a reason for hiding this comment

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

Looking great! A few nitpick comments on the code - please feel free to fix or ignore as you see fit.

A few other comments below to be addressed. Happy to talk these through if you'd like, just let me know.

Sorting
We should sort the results in a format expected by the user - currently they're sorted lexicographic which put 1, 10, 11 before 2, 3, 4. I think a user would expect these to be naturally sorted (localCompare()?).

Image

See PlanX for reference -

Image

A quick glance at the docs didn't show a param for this, so we might need to do this ourselves. We probably want to account for MATCH and MATCH_DESCRIPTION here - we don't want to sort naturally, but discounting exactness here. I guess we could group results by MATCH and then sort the subgroups? You could write this by hand or reach for something like orderBy() from lodash which allows sorting by multiple properties (docs).

Number of results
This might be too restrictive - populateResults(options.slice(0, 5))

It's possible that a user would type an address to the greatest accuracy they can (e.g. a full postcode, or street name) and still not be able to select their address. We're fetching up to 100 records from the OS on each request - should we just show them all here? If we decide that a more limited subset is best (e.g 30, 50?) we should match this value with maxResults so that we're never over-fetching 👍

name: "osApiKey",
type: "String",
values: "https://osdatahub.os.uk/plans",
required: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This should be optional (as long as a proxyEndpoint is provided). I don't think the docs let us express that level of conditionality so it's probably best we just say required: false here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for updating the links here 💪

@@ -0,0 +1,63 @@
@import "govuk-frontend/dist/govuk/index";
// @import "accessible-autocomplete";
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Could we tidy up this commented out line?

: html`
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/accessible-autocomplete.min.css"
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like we missed this link when updating the package. I guess this should point to 3.0.1 both here and in the other autocomplete?

Comment on lines 95 to 98
// min query length of 3 before fetching
if (query.length >= 3) {
this._fetchData(query, populateResults);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is great! I think ideally we'd use the same logic before displaying the tNoResults value also. Currently I get "no addressed found" as soon as I type the first character.

Copy link
Contributor

Choose a reason for hiding this comment

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

It actually looks like there might be a parameter for this we can use? https://github.com/alphagov/accessible-autocomplete?tab=readme-ov-file#minlength-default-0

type ArrowStyleEnum = "default" | "light";
type LabelStyleEnum = "responsive" | "static";

// debounce function
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Slightly redundant comment?

import styles from "./styles.scss?inline";
import { getServiceURL } from "../../lib/ordnanceSurvey";

// https://apidocs.os.uk/docs/os-places-lpi-output
Copy link
Contributor

Choose a reason for hiding this comment

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

This link doesn't work for me - I just get redirected to their docs homepage.

Should it be https://docs.os.uk/os-apis/accessing-os-apis/os-places-api/technical-specification/find?

Comment on lines 9 to 11
type Address = {
LPI: any;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Where possible, I'd recommend avoiding the use of any.

A few options -

  • Type out the whole object (using something like https://transform.tools/json-to-typescript to copy the response object from the OS docs)
    • Not actually a great solution as it's potentially brittle if they change their API, and adds a lot of boilerplate here for us to maintain without that much benefit
  • Using unknown
    • Much better than any - means we can code defensively
  • Sketching out just the shape we care about, so that we at least get type safety within this library (e.g. LPI.ADDRESS on line 108`)

I'd probably go for the third option here 👍

@jmcbroom
Copy link
Collaborator Author

jmcbroom commented Aug 4, 2025

hey @DafyddLlyr, thanks for your comments and the helpful example search -- I did choose to dedupe based on UPRN as the Find endpoint returns some duplicate addresses, example here:

{
  "LPI" : {
    "UPRN" : "49051071",
    "ADDRESS" : "1, RHYD-Y-BONT, PENPARCAU, ABERYSTWYTH, CEREDIGION, SY23 1SR",
    "USRN" : "47100668",
    "LPI_KEY" : "6820L000055750",
    "PAO_START_NUMBER" : "1",
    "STREET_DESCRIPTION" : "RHYD-Y-BONT",
    "LOCALITY_NAME" : "PENPARCAU",
    "TOWN_NAME" : "ABERYSTWYTH",
    "ADMINISTRATIVE_AREA" : "CEREDIGION",
    "POSTCODE_LOCATOR" : "SY23 1SR",
    "RPC" : "1",
    "X_COORDINATE" : 259166.13,
    "Y_COORDINATE" : 280339.26,
    "STATUS" : "APPROVED",
    "LOGICAL_STATUS_CODE" : "1",
    "CLASSIFICATION_CODE" : "RD03",
    "CLASSIFICATION_CODE_DESCRIPTION" : "Semi-Detached",
    "LOCAL_CUSTODIAN_CODE" : 6820,
    "LOCAL_CUSTODIAN_CODE_DESCRIPTION" : "CEREDIGION",
    "COUNTRY_CODE" : "W",
    "COUNTRY_CODE_DESCRIPTION" : "This record is within Wales",
    "POSTAL_ADDRESS_CODE" : "D",
    "POSTAL_ADDRESS_CODE_DESCRIPTION" : "A record which is linked to PAF",
    "BLPU_STATE_CODE" : "2",
    "BLPU_STATE_CODE_DESCRIPTION" : "In use",
    "TOPOGRAPHY_LAYER_TOID" : "osgb1000020602516",
    "WARD_CODE" : "W05001301",
    "PARISH_CODE" : "W04000359",
    "LAST_UPDATE_DATE" : "10/02/2016",
    "ENTRY_DATE" : "24/11/2006",
    "BLPU_STATE_DATE" : "06/10/2011",
    "STREET_STATE_CODE" : "2",
    "STREET_STATE_CODE_DESCRIPTION" : "Open",
    "LPI_LOGICAL_STATUS_CODE" : "1",
    "LPI_LOGICAL_STATUS_CODE_DESCRIPTION" : "APPROVED",
    "LANGUAGE" : "CY",
    "MATCH" : 1.0,
    "MATCH_DESCRIPTION" : "EXACT"
  }
}
{
  "LPI" : {
    "UPRN" : "49051071",
    "ADDRESS" : "1, RHYD-Y-BONT, PENPARCAU, ABERYSTWYTH, CEREDIGION, SY23 1SR",
    "USRN" : "47100668",
    "LPI_KEY" : "6820L000027970",
    "PAO_START_NUMBER" : "1",
    "STREET_DESCRIPTION" : "RHYD-Y-BONT",
    "LOCALITY_NAME" : "PENPARCAU",
    "TOWN_NAME" : "ABERYSTWYTH",
    "ADMINISTRATIVE_AREA" : "CEREDIGION",
    "POSTCODE_LOCATOR" : "SY23 1SR",
    "RPC" : "1",
    "X_COORDINATE" : 259166.13,
    "Y_COORDINATE" : 280339.26,
    "STATUS" : "APPROVED",
    "LOGICAL_STATUS_CODE" : "1",
    "CLASSIFICATION_CODE" : "RD03",
    "CLASSIFICATION_CODE_DESCRIPTION" : "Semi-Detached",
    "LOCAL_CUSTODIAN_CODE" : 6820,
    "LOCAL_CUSTODIAN_CODE_DESCRIPTION" : "CEREDIGION",
    "COUNTRY_CODE" : "W",
    "COUNTRY_CODE_DESCRIPTION" : "This record is within Wales",
    "POSTAL_ADDRESS_CODE" : "D",
    "POSTAL_ADDRESS_CODE_DESCRIPTION" : "A record which is linked to PAF",
    "BLPU_STATE_CODE" : "2",
    "BLPU_STATE_CODE_DESCRIPTION" : "In use",
    "TOPOGRAPHY_LAYER_TOID" : "osgb1000020602516",
    "WARD_CODE" : "W05001301",
    "PARISH_CODE" : "W04000359",
    "LAST_UPDATE_DATE" : "10/02/2016",
    "ENTRY_DATE" : "24/11/2006",
    "BLPU_STATE_DATE" : "06/10/2011",
    "STREET_STATE_CODE" : "2",
    "STREET_STATE_CODE_DESCRIPTION" : "Open",
    "LPI_LOGICAL_STATUS_CODE" : "1",
    "LPI_LOGICAL_STATUS_CODE_DESCRIPTION" : "APPROVED",
    "LANGUAGE" : "EN",
    "MATCH" : 1.0,
    "MATCH_DESCRIPTION" : "EXACT"
  }
}

as far as I can tell the main difference is the USRN and LPI_KEY (which I'd guess is because of the USRN difference?). I assume this deduping is OK since it's not happening in the address-autocomplete component.. but not 100% sure.

@DafyddLlyr
Copy link
Contributor

DafyddLlyr commented Aug 4, 2025

@jmcbroom This is a fun UK one to welcome you to the team 😂 The OS Places API is returning both English and Welsh results 🏴󠁧󠁢󠁷󠁬󠁳󠁿 🏴󠁧󠁢󠁥󠁮󠁧󠁿

{
  "LPI" : {
    ...
    "LANGUAGE" : "CY",
  }
}
{
  "LPI" : {
    ...
    "LANGUAGE" : "EN",
  }
}

It's not actually obvious in this instance as this is an all Welsh address example I've unwittingly provided sorry - if you try a Cardiff postcode you'll probably spot a difference in Cardiff / Caerdydd in the address line for example.

As PlanX is currently England only we can safely just set the lr param to EN (default is "EN, CY") (docs).

@jmcbroom
Copy link
Collaborator Author

jmcbroom commented Aug 6, 2025

thanks for catching that!

also note: I kept the max_results fetched at 100, in order to most closely match the address-autocomplete search results for the example postcode (SY23 1SR).

Copy link
Contributor

@DafyddLlyr DafyddLlyr left a comment

Choose a reason for hiding this comment

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

Looking great @jmcbroom - thanks for resolving all this 👍

Next steps would be to merge this and then publish a new version of the repo so that we can integrate this into LPS.

@jmcbroom jmcbroom merged commit 744042c into main Aug 8, 2025
5 checks passed
@jmcbroom jmcbroom deleted the jimmy/geocode-autocomplete branch August 8, 2025 12:11
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.

4 participants