Skip to content

Commit 4c5fd9a

Browse files
authored
Merge pull request #42 from labd/bias
feat: bias and origin
2 parents c3c2d4f + 2c987f0 commit 4c5fd9a

7 files changed

Lines changed: 116 additions & 13 deletions

File tree

.changeset/long-dryers-itch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-loqate": minor
3+
---
4+
5+
Implement Bias and Origin parameters for use with capture v4 key

README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,19 @@ import 'react-loqate/dist/index.css';
3232

3333
### Props
3434

35-
| name | type | required | example | description |
36-
| ---------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------- | ---------------------------------------- |
37-
| apiKey | string | yes | "AA11-AA11-AA11-AA11" | Loqate API key |
38-
| locale | string | yes | "en-GB" | Language to be used |
39-
| onSelect | (address) => void | yes | address => console.log(address) | Callback with for Loqate response |
40-
| countries | string[] | no | ["GB", "NL"] | Countries to search in |
41-
| limit | number | no | 10 | Number of options to show |
42-
| classes | `{ input?: string, list?: string, listItem?: string}` | no | { list: 'list' } | Classnames for the components |
43-
| components | see [Customization](#Customization) | no | { Input: CustomInput, List: CustomList, ListItem: CustomListItem, } | Components to overwrite the default ones |
44-
| inline | boolean | no | true | Render results inline with the input |
45-
| debounce | number | no | 100 | Debounce the calls to the Loqate API |
35+
| name | type | required | example | description |
36+
| ---------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
37+
| apiKey | string | yes | "AA11-AA11-AA11-AA11" | Loqate API key |
38+
| locale | string | yes | "en-GB" | Language to be used |
39+
| onSelect | (address) => void | yes | address => console.log(address) | Callback with for Loqate response |
40+
| countries | string[] | no | ["GB", "NL"] | Countries to search in |
41+
| limit | number | no | 10 | Number of options to show |
42+
| classes | `{ input?: string, list?: string, listItem?: string}` | no | { list: 'list' } | Classnames for the components |
43+
| components | see [Customization](#Customization) | no | { Input: CustomInput, List: CustomList, ListItem: CustomListItem, } | Components to overwrite the default ones |
44+
| inline | boolean | no | true | Render results inline with the input |
45+
| debounce | number | no | 100 | Debounce the calls to the Loqate API |
46+
| bias | boolean | no | true | Bias feature when using capture v4 enabled key.<br>Requires origin to be set. |
47+
| origin | string | no | "93.184.216.34" | Name or ISO 2 or 3 character code of a country, WGS84 coordinates (comma separated) or IP address |
4648

4749
### Customization
4850

src/__tests__/serverHandlers.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,24 @@ export const errorHandler = http.get(
6565
});
6666
}
6767
);
68+
69+
export const biasHandler = http.get(
70+
`${LOQATE_BASE_URL}/${LOQATE_FIND_URL}`,
71+
({ request }) => {
72+
const url = new URL(request.url);
73+
const bias = url.searchParams.get('Bias');
74+
const origin = url.searchParams.get('Origin');
75+
if (bias === 'true' && origin !== '') {
76+
return HttpResponse.json({
77+
Items: {
78+
Id: 'GB|RM|ENG|TAMWORTH-PICCADILLY',
79+
Type: 'Locality',
80+
Text: 'Piccadilly, Tamworth, B78',
81+
Highlight: '0-10',
82+
Description: '174 Addresses',
83+
},
84+
});
85+
}
86+
throw new Error(`no bias`);
87+
}
88+
);

src/index.test.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { selection } from './__tests__/__fixtures__/selection';
88
import { server } from './__tests__/server';
99
import { errorHandler } from './__tests__/serverHandlers';
1010
import AddressSearch from './index';
11+
import Loqate from './utils/Loqate';
1112

1213
global.fetch = fetch;
1314

@@ -346,3 +347,33 @@ it('lets its errors be caught by an ErrorBoundary', async () => {
346347

347348
expect(baseElement).toMatchSnapshot();
348349
});
350+
351+
it('accepts origin and bias options', async () => {
352+
const findSpy = vi.spyOn(Loqate.prototype, 'find');
353+
354+
render(
355+
<AddressSearch
356+
locale="en-GB"
357+
apiKey="some-key"
358+
onSelect={vi.fn()}
359+
limit={5}
360+
inline
361+
bias={true}
362+
origin="GB"
363+
/>
364+
);
365+
366+
const input = screen.getByRole('textbox');
367+
input.focus();
368+
fireEvent.change(input, { target: { value: 'a' } });
369+
370+
expect(findSpy).toHaveBeenCalledWith({
371+
bias: true,
372+
containerId: undefined,
373+
countries: undefined,
374+
language: 'en',
375+
limit: 5,
376+
origin: 'GB',
377+
text: 'a',
378+
});
379+
});

src/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export interface Props {
2929
inline?: boolean;
3030
debounce?: number;
3131
apiUrl?: string;
32+
bias?: boolean;
33+
origin?: string;
3234
}
3335

3436
interface Components {
@@ -129,6 +131,8 @@ function AddressSearch(props: Props): JSX.Element {
129131
inline,
130132
debounce,
131133
apiUrl,
134+
bias,
135+
origin,
132136
} = props;
133137
const loqate = useMemo(() => Loqate.create(apiKey, apiUrl), [apiKey]);
134138

@@ -148,6 +152,8 @@ function AddressSearch(props: Props): JSX.Element {
148152
text,
149153
containerId,
150154
language: loqateLanguage(locale),
155+
origin,
156+
bias,
151157
});
152158

153159
if (res.Items) {

src/utils/Loqate.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ interface FindQuery {
1212
countries?: string[];
1313
limit?: number;
1414
containerId?: string;
15+
origin?: string;
16+
bias?: boolean;
1517
}
1618

1719
type LoqateResponse = { Items?: Item[] | LoqateErrorItem[] };
@@ -43,14 +45,25 @@ class Loqate {
4345
}
4446

4547
public async find(query: FindQuery): Promise<LoqateNoErrorResponse> {
46-
const { text, countries = [], containerId, language, limit } = query;
48+
const {
49+
text,
50+
countries = [],
51+
containerId,
52+
language,
53+
limit,
54+
origin,
55+
bias,
56+
} = query;
4757

4858
const params = new URLSearchParams({
4959
Text: text,
5060
Countries: countries.join(','),
5161
language,
5262
Key: this.key,
63+
Origin: origin ? origin : '',
64+
Bias: bias ? 'true' : 'false',
5365
});
66+
5467
if (containerId) {
5568
params.set('Container', containerId);
5669
}

src/utils/__tests__/Loqate.test.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest';
33
import { selection } from '../../__tests__/__fixtures__/selection';
44
import { suggestions } from '../../__tests__/__fixtures__/suggestions';
55
import { server } from '../../__tests__/server';
6-
import { errorHandler } from '../../__tests__/serverHandlers';
6+
import { biasHandler, errorHandler } from '../../__tests__/serverHandlers';
77
import Loqate from '../Loqate';
88

99
global.fetch = fetch;
@@ -41,6 +41,31 @@ describe('Loqate', () => {
4141
expect({ Items }).toEqual(suggestions);
4242
});
4343

44+
it('accepts bias and origin', async () => {
45+
server.use(biasHandler);
46+
47+
const loqate = Loqate.create('some-key');
48+
const { Items } = await loqate.find({
49+
text: 'some-text',
50+
language: 'some-language',
51+
countries: ['GB', 'US'],
52+
limit: 10,
53+
containerId: 'some-container-id',
54+
bias: true,
55+
origin: '93.184.216.34',
56+
});
57+
58+
expect({ Items }).toEqual({
59+
Items: {
60+
Id: 'GB|RM|ENG|TAMWORTH-PICCADILLY',
61+
Type: 'Locality',
62+
Text: 'Piccadilly, Tamworth, B78',
63+
Highlight: '0-10',
64+
Description: '174 Addresses',
65+
},
66+
});
67+
});
68+
4469
it('should throw errors', async () => {
4570
server.use(errorHandler);
4671

0 commit comments

Comments
 (0)