Repository: dhsc-govuk/FingertipsNext
Pull request #404: DHSCFT-571: Use new getAreas call to get all selected areas in one request
Author: login: alibombaye
Created: 2025-04-04T11:35:53Z | Merged: 2025-04-07T14:04:13Z

# Description

Jira ticket: [DHSCFT-571](https://bjss-enterprise.atlassian.net/browse/DHSCFT-571)

Updates to use new endpoint to get areas selected data in one api request.

<img width="1366" alt="Screenshot 2025-04-04 at 16 34 59" src="https://github.com/user-attachments/assets/d088f3aa-73e4-4b57-a3e1-19d85ebd41b4" />


## Validation

Tested against the API and MSW



Diff:
diff --git a/api/definition/swagger.yaml b/api/definition/swagger.yaml
index 8319a5f22..95ed69f51 100644
--- a/api/definition/swagger.yaml
+++ b/api/definition/swagger.yaml
@@ -121,8 +121,9 @@ paths:
       tags:
         - areas
       summary: Get multiple areas
-      description: Get the basic details without children, parent relationships etc.
-        for 1 or more areas
+      description:
+        Get the basic details without children, parent relationships etc.
+        for 1 or more areas. Will return duplicate of areas that are applicable to multiple areaTypes.
       operationId: getAreas
       parameters:
         - $ref: "#/components/parameters/area_codes"
@@ -282,7 +283,7 @@ paths:
         - indicators
       summary: Get quartile values for indicators
       description: |
-        Get quartile information for indicators including 
+        Get quartile information for indicators including
       parameters:
         - $ref: "#/components/parameters/indicator_ids"
         - $ref: "#/components/parameters/area_code"
@@ -310,20 +311,62 @@ components:
   schemas:
     IndicatorPolarity: # Define enum globally
       type: string
-      enum: [ Unknown, NoJudgement, LowIsGood, HighIsGood ]
-      x-enum-varnames: [ Unknown, NoJudgement, LowIsGood, HighIsGood ]
+      enum: [Unknown, NoJudgement, LowIsGood, HighIsGood]
+      x-enum-varnames: [Unknown, NoJudgement, LowIsGood, HighIsGood]
     BenchmarkComparisonMethod:
       type: string
       example: CIOverlappingReferenceValue95
       description: the benchmark comparison method used
-      enum: [ Unknown, Quintiles, CIOverlappingReferenceValue95, CIOverlappingReferenceValue99_8 ]
-      x-enum-varnames: [ Unknown, Quintiles, CIOverlappingReferenceValue95, CIOverlappingReferenceValue99_8 ]
+      enum:
+        [
+          Unknown,
+          Quintiles,
+          CIOverlappingReferenceValue95,
+          CIOverlappingReferenceValue99_8,
+        ]
+      x-enum-varnames:
+        [
+          Unknown,
+          Quintiles,
+          CIOverlappingReferenceValue95,
+          CIOverlappingReferenceValue99_8,
+        ]
     BenchmarkOutcome:
       type: string
       example: Lower
       description: benchmark outcome
-      enum: [ NotCompared, Lowest, Lower, Low, Middle, High, Higher, Highest, Better, Best, Worse, Worst, Similar ]
-      x-enum-varnames: [ NotCompared, Lowest, Lower, Low, Middle, High, Higher, Highest, Better, Best, Worse, Worst, Similar ]
+      enum:
+        [
+          NotCompared,
+          Lowest,
+          Lower,
+          Low,
+          Middle,
+          High,
+          Higher,
+          Highest,
+          Better,
+          Best,
+          Worse,
+          Worst,
+          Similar,
+        ]
+      x-enum-varnames:
+        [
+          NotCompared,
+          Lowest,
+          Lower,
+          Low,
+          Middle,
+          High,
+          Higher,
+          Highest,
+          Better,
+          Best,
+          Worse,
+          Worst,
+          Similar,
+        ]
     AreaType:
       type: object
       description: An area type e.g. PCN or GP
@@ -483,17 +526,18 @@ components:
           description: The statistical trend that applies to the data point,
             given the preceding data. Will only be calculated if there are at
             least 5 data points to use.
-          enum: [
-            'Not yet calculated',
-            'Cannot be calculated',
-            'Increasing',
-            'Decreasing',
-            'No significant change',
-            'Increasing and getting better',
-            'Increasing and getting worse',
-            'Decreasing and getting better',
-            'Decreasing and getting worse'
-          ]
+          enum:
+            [
+              "Not yet calculated",
+              "Cannot be calculated",
+              "Increasing",
+              "Decreasing",
+              "No significant change",
+              "Increasing and getting better",
+              "Increasing and getting worse",
+              "Decreasing and getting better",
+              "Decreasing and getting worse",
+            ]
         isAggregate:
           type: boolean
           description: Indicates if the datapoint is an aggregate point.
@@ -508,7 +552,7 @@ components:
               type: string
               example: HighIsGood
               description: the type of polarity applied to the outcome
-              enum: [ NoJudgement, LowIsGood, HighIsGood ]
+              enum: [NoJudgement, LowIsGood, HighIsGood]
             benchmarkAreaCode:
               type: string
               example: E92000001
@@ -623,7 +667,7 @@ components:
             $ref: "#/components/schemas/HealthDataForArea"
     QuartileData:
       type: object
-      description: Quartile data for an indicator plus supporting information 
+      description: Quartile data for an indicator plus supporting information
       properties:
         indicatorId:
           type: integer
@@ -633,30 +677,30 @@ components:
           type: integer
           format: int32
           example: 2023
-          description: The year that the data point is for        
+          description: The year that the data point is for
         polarity:
           $ref: "#/components/schemas/IndicatorPolarity"
         q0Value:
-           type: number
-           description: Quartile Q0 value - the minimum value
+          type: number
+          description: Quartile Q0 value - the minimum value
         q1Value:
-           type: number
-           description: Quartile Q1 value - the lower quartile value
+          type: number
+          description: Quartile Q1 value - the lower quartile value
         q2Value:
-           type: number
-           description: Quartile Q2 value - the median value
+          type: number
+          description: Quartile Q2 value - the median value
         q3Value:
-           type: number
-           description: Quartile Q3 value - the upper quartile value
+          type: number
+          description: Quartile Q3 value - the upper quartile value
         q4Value:
-           type: number
-           description: Quartile Q4 value - the maximum value
+          type: number
+          description: Quartile Q4 value - the maximum value
         areaValue:
           type: number
-          description: the average value for the area requested for comparison 
+          description: the average value for the area requested for comparison
         ancestorValue:
           type: number
-          description: the average value for the ancestor area requested for comparison 
+          description: the average value for the ancestor area requested for comparison
         englandValue:
           type: number
           description: the average value for England for comparison
diff --git a/frontend/fingertips-frontend/app/(home)/page.test.tsx b/frontend/fingertips-frontend/app/(home)/page.test.tsx
index 34568e2dd..603d04208 100644
--- a/frontend/fingertips-frontend/app/(home)/page.test.tsx
+++ b/frontend/fingertips-frontend/app/(home)/page.test.tsx
@@ -5,12 +5,6 @@
 import { SearchParams, SearchStateParams } from '@/lib/searchStateManager';
 import HomePage from './page';
 import { getAreaFilterData } from '@/lib/areaFilterHelpers/getAreaFilterData';
-import { AreasApi } from '@/generated-sources/ft-api-client';
-import { mockDeep } from 'jest-mock-extended';
-import {
-  API_CACHE_CONFIG,
-  ApiClientFactory,
-} from '@/lib/apiClient/apiClientFactory';
 import {
   allAreaTypes,
   nhsRegionsAreaType,
@@ -25,17 +19,21 @@ import {
   londonNHSRegion,
 } from '@/mock/data/areas/nhsRegionsAreas';
 import { areaCodeForEngland } from '@/lib/chartHelpers/constants';
+import { getSelectedAreasDataByAreaType } from '@/lib/areaFilterHelpers/getSelectedAreasData';
 
 jest.mock('@/lib/areaFilterHelpers/getAreaFilterData');
+jest.mock('@/lib/areaFilterHelpers/getSelectedAreasData');
 jest.mock('@/components/pages/home');
 
 const mockGetAreaFilterData = getAreaFilterData as jest.MockedFunction<
   typeof getAreaFilterData
 >;
 
-const mockAreasApi = mockDeep<AreasApi>();
-
-ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+const mockGetSelectedAreasDataByAreaType =
+  getSelectedAreasDataByAreaType as jest.MockedFunction<
+    typeof getSelectedAreasDataByAreaType
+  >;
+mockGetSelectedAreasDataByAreaType.mockResolvedValue([]);
 
 async function generateSearchParams(value: SearchStateParams) {
   return value;
@@ -88,11 +86,14 @@ describe('Home page', () => {
       expect(page.props.areaFilterData).toEqual(areaFilterData);
     });
 
-    it('should pass the selectedAreasData prop with data from getArea for each areaSelected', async () => {
-      mockAreasApi.getArea.mockResolvedValueOnce(eastEnglandNHSRegion);
-      mockAreasApi.getArea.mockResolvedValueOnce(londonNHSRegion);
+    it('should pass the selectedAreasData prop with data from getSelectedAreasDataByAreaType', async () => {
+      mockGetSelectedAreasDataByAreaType.mockResolvedValue([
+        eastEnglandNHSRegion,
+        londonNHSRegion,
+      ]);
 
       const searchState: SearchStateParams = {
+        [SearchParams.AreaTypeSelected]: 'nhs-regions',
         [SearchParams.AreasSelected]: ['E40000007', 'E40000003'],
       };
 
@@ -100,19 +101,9 @@ describe('Home page', () => {
         searchParams: generateSearchParams(searchState),
       });
 
-      expect(mockAreasApi.getArea).toHaveBeenNthCalledWith(
-        1,
-        {
-          areaCode: eastEnglandNHSRegion.code,
-        },
-        API_CACHE_CONFIG
-      );
-      expect(mockAreasApi.getArea).toHaveBeenNthCalledWith(
-        2,
-        {
-          areaCode: londonNHSRegion.code,
-        },
-        API_CACHE_CONFIG
+      expect(mockGetSelectedAreasDataByAreaType).toHaveBeenCalledWith(
+        ['E40000007', 'E40000003'],
+        'nhs-regions'
       );
       expect(page.props.selectedAreasData).toEqual([
         eastEnglandNHSRegion,
@@ -136,12 +127,10 @@ describe('Home page', () => {
         updatedSearchState,
       });
 
-      mockAreasApi.getArea.mockResolvedValueOnce({
-        ...eastEnglandNHSRegion,
-      });
-      mockAreasApi.getArea.mockResolvedValueOnce({
-        ...londonNHSRegion,
-      });
+      mockGetSelectedAreasDataByAreaType.mockResolvedValue([
+        eastEnglandNHSRegion,
+        londonNHSRegion,
+      ]);
 
       const page = await HomePage({
         searchParams: generateSearchParams(initialSearchState),
diff --git a/frontend/fingertips-frontend/app/(home)/page.tsx b/frontend/fingertips-frontend/app/(home)/page.tsx
index 2a0e9226d..3f38291d5 100644
--- a/frontend/fingertips-frontend/app/(home)/page.tsx
+++ b/frontend/fingertips-frontend/app/(home)/page.tsx
@@ -7,12 +7,10 @@ import {
   SearchStateParams,
 } from '@/lib/searchStateManager';
 import { connection } from 'next/server';
-import {
-  API_CACHE_CONFIG,
-  ApiClientFactory,
-} from '@/lib/apiClient/apiClientFactory';
 import { ErrorPage } from '@/components/pages/error';
 import { getAreaFilterData } from '@/lib/areaFilterHelpers/getAreaFilterData';
+import { getSelectedAreasDataByAreaType } from '@/lib/areaFilterHelpers/getSelectedAreasData';
+import { AreaTypeKeys } from '@/lib/areaFilterHelpers/areaType';
 
 export default async function Page(
   props: Readonly<{
@@ -25,20 +23,16 @@ export default async function Page(
   const {
     [SearchParams.SearchedIndicator]: searchedIndicator,
     [SearchParams.AreasSelected]: areasSelected,
+    [SearchParams.AreaTypeSelected]: areaTypeSelected,
   } = stateManager.getSearchState();
 
   try {
     await connection();
 
-    const areasApi = ApiClientFactory.getAreasApiClient();
-    const selectedAreasData =
-      areasSelected && areasSelected.length > 0
-        ? await Promise.all(
-            areasSelected.map((area) =>
-              areasApi.getArea({ areaCode: area }, API_CACHE_CONFIG)
-            )
-          )
-        : [];
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      areasSelected,
+      areaTypeSelected as AreaTypeKeys
+    );
 
     const {
       availableAreaTypes,
diff --git a/frontend/fingertips-frontend/app/chart/page.test.tsx b/frontend/fingertips-frontend/app/chart/page.test.tsx
index 657fedce7..1110bcc0c 100644
--- a/frontend/fingertips-frontend/app/chart/page.test.tsx
+++ b/frontend/fingertips-frontend/app/chart/page.test.tsx
@@ -5,11 +5,8 @@
 import ChartPage from './page';
 import { SearchParams, SearchStateParams } from '@/lib/searchStateManager';
 import { mockDeep } from 'jest-mock-extended';
-import {
-  API_CACHE_CONFIG,
-  ApiClientFactory,
-} from '@/lib/apiClient/apiClientFactory';
-import { AreasApi, IndicatorsApi } from '@/generated-sources/ft-api-client';
+import { ApiClientFactory } from '@/lib/apiClient/apiClientFactory';
+import { IndicatorsApi } from '@/generated-sources/ft-api-client';
 import { getAreaFilterData } from '@/lib/areaFilterHelpers/getAreaFilterData';
 import {
   allAreaTypes,
@@ -27,6 +24,7 @@ import {
 import { IIndicatorSearchService } from '@/lib/search/searchTypes';
 import { SearchServiceFactory } from '@/lib/search/searchServiceFactory';
 import { generateIndicatorDocument } from '@/lib/search/mockDataHelper';
+import { getSelectedAreasDataByAreaType } from '@/lib/areaFilterHelpers/getSelectedAreasData';
 
 const mockIndicatorsApi = mockDeep<IndicatorsApi>();
 ApiClientFactory.getIndicatorsApiClient = () => mockIndicatorsApi;
@@ -36,14 +34,17 @@ jest.mock('@/components/organisms/ThematicMap/thematicMapHelpers.ts', () => ({
 }));
 
 jest.mock('@/lib/areaFilterHelpers/getAreaFilterData');
-
 const mockGetAreaFilterData = getAreaFilterData as jest.MockedFunction<
   typeof getAreaFilterData
 >;
 mockGetAreaFilterData.mockResolvedValue({});
 
-const mockAreasApi = mockDeep<AreasApi>();
-ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+jest.mock('@/lib/areaFilterHelpers/getSelectedAreasData');
+const mockGetSelectedAreasDataByAreaType =
+  getSelectedAreasDataByAreaType as jest.MockedFunction<
+    typeof getSelectedAreasDataByAreaType
+  >;
+mockGetSelectedAreasDataByAreaType.mockResolvedValue([]);
 
 const mockIndicatorSearchService = mockDeep<IIndicatorSearchService>();
 SearchServiceFactory.getIndicatorSearchService = () =>
@@ -101,13 +102,16 @@ describe('Chart Page', () => {
       expect(page.props.areaFilterData).toEqual(areaFilterData);
     });
 
-    it('should pass the selectedAreasData prop with data from getArea for each areaSelected', async () => {
-      mockAreasApi.getArea.mockResolvedValueOnce(eastEnglandNHSRegion);
-      mockAreasApi.getArea.mockResolvedValueOnce(londonNHSRegion);
+    it('should pass the selectedAreasData prop with data from getSelectedAreasDataByAreaType', async () => {
+      mockGetSelectedAreasDataByAreaType.mockResolvedValue([
+        eastEnglandNHSRegion,
+        londonNHSRegion,
+      ]);
 
       const searchState: SearchStateParams = {
         [SearchParams.SearchedIndicator]: 'testing',
         [SearchParams.IndicatorsSelected]: ['1', '2'],
+        [SearchParams.AreaTypeSelected]: 'nhs-regions',
         [SearchParams.AreasSelected]: ['E40000007', 'E40000003'],
       };
 
@@ -115,19 +119,9 @@ describe('Chart Page', () => {
         searchParams: generateSearchParams(searchState),
       });
 
-      expect(mockAreasApi.getArea).toHaveBeenNthCalledWith(
-        1,
-        {
-          areaCode: eastEnglandNHSRegion.code,
-        },
-        API_CACHE_CONFIG
-      );
-      expect(mockAreasApi.getArea).toHaveBeenNthCalledWith(
-        2,
-        {
-          areaCode: londonNHSRegion.code,
-        },
-        API_CACHE_CONFIG
+      expect(mockGetSelectedAreasDataByAreaType).toHaveBeenCalledWith(
+        ['E40000007', 'E40000003'],
+        'nhs-regions'
       );
       expect(page.props.selectedAreasData).toEqual([
         eastEnglandNHSRegion,
diff --git a/frontend/fingertips-frontend/app/chart/page.tsx b/frontend/fingertips-frontend/app/chart/page.tsx
index b01821596..135204e06 100644
--- a/frontend/fingertips-frontend/app/chart/page.tsx
+++ b/frontend/fingertips-frontend/app/chart/page.tsx
@@ -4,12 +4,8 @@ import {
   SearchStateManager,
   SearchStateParams,
 } from '@/lib/searchStateManager';
-
-import {
-  API_CACHE_CONFIG,
-  ApiClientFactory,
-} from '@/lib/apiClient/apiClientFactory';
-
+import { getSelectedAreasDataByAreaType } from '@/lib/areaFilterHelpers/getSelectedAreasData';
+import { AreaTypeKeys } from '@/lib/areaFilterHelpers/areaType';
 import { ViewsContext } from '@/components/views/ViewsContext';
 import { SearchServiceFactory } from '@/lib/search/searchServiceFactory';
 import { getAreaFilterData } from '@/lib/areaFilterHelpers/getAreaFilterData';
@@ -26,6 +22,7 @@ export default async function ChartPage(
     const {
       [SearchParams.AreasSelected]: areaCodes,
       [SearchParams.IndicatorsSelected]: indicatorsSelected,
+      [SearchParams.AreaTypeSelected]: areaTypeSelected,
     } = stateManager.getSearchState();
 
     const areasSelected = areaCodes ?? [];
@@ -45,16 +42,11 @@ export default async function ChartPage(
             )
           ).filter((indicatorDocument) => indicatorDocument !== undefined)
         : [];
-    const areasApi = ApiClientFactory.getAreasApiClient();
 
-    const selectedAreasData =
-      areasSelected && areasSelected.length > 0
-        ? await Promise.all(
-            areasSelected.map((area) =>
-              areasApi.getArea({ areaCode: area }, API_CACHE_CONFIG)
-            )
-          )
-        : [];
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      areasSelected,
+      areaTypeSelected as AreaTypeKeys
+    );
 
     const {
       availableAreaTypes,
diff --git a/frontend/fingertips-frontend/app/results/page.test.tsx b/frontend/fingertips-frontend/app/results/page.test.tsx
index 8297c75bb..78bf8b6c2 100644
--- a/frontend/fingertips-frontend/app/results/page.test.tsx
+++ b/frontend/fingertips-frontend/app/results/page.test.tsx
@@ -10,10 +10,6 @@ import {
 } from '@/lib/search/searchTypes';
 import { SearchServiceFactory } from '@/lib/search/searchServiceFactory';
 import { mockDeep } from 'jest-mock-extended';
-import {
-  API_CACHE_CONFIG,
-  ApiClientFactory,
-} from '@/lib/apiClient/apiClientFactory';
 import { AreasApi } from '@/generated-sources/ft-api-client';
 import {
   mockAreaDataForNHSRegion,
@@ -31,13 +27,20 @@ import {
 import { areaCodeForEngland } from '@/lib/chartHelpers/constants';
 import { getAreaFilterData } from '@/lib/areaFilterHelpers/getAreaFilterData';
 import { generateIndicatorDocument } from '@/lib/search/mockDataHelper';
+import { getSelectedAreasDataByAreaType } from '@/lib/areaFilterHelpers/getSelectedAreasData';
 
 jest.mock('@/lib/areaFilterHelpers/getAreaFilterData');
+jest.mock('@/lib/areaFilterHelpers/getSelectedAreasData');
 
 const mockGetAreaFilterData = getAreaFilterData as jest.MockedFunction<
   typeof getAreaFilterData
 >;
 
+const mockGetSelectedAreasDataByAreaType =
+  getSelectedAreasDataByAreaType as jest.MockedFunction<
+    typeof getSelectedAreasDataByAreaType
+  >;
+
 const mockIndicatorSearchResults: IndicatorDocument[] = [
   generateIndicatorDocument('1'),
   generateIndicatorDocument('2'),
@@ -51,8 +54,6 @@ jest.mock('@/components/pages/results');
 SearchServiceFactory.getIndicatorSearchService = () =>
   mockIndicatorSearchService;
 
-ApiClientFactory.getAreasApiClient = () => mockAreasApi;
-
 const searchParams: SearchStateParams = {
   [SearchParams.SearchedIndicator]: 'testing',
 };
@@ -180,6 +181,7 @@ describe('Results Page', () => {
       };
 
       mockGetAreaFilterData.mockResolvedValue(areaFilterData);
+      mockGetSelectedAreasDataByAreaType.mockResolvedValue([]);
 
       const searchState: SearchStateParams = {
         ...searchParams,
@@ -194,14 +196,17 @@ describe('Results Page', () => {
       expect(page.props.areaFilterData).toEqual(areaFilterData);
     });
 
-    it('should pass the selectedAreasData prop with data from getArea for each areaSelected', async () => {
+    it('should pass the selectedAreasData prop with data from getSelectedAreasDataByAreaType', async () => {
       mockGetAreaFilterData.mockResolvedValue({});
-      mockAreasApi.getArea.mockResolvedValueOnce(eastEnglandNHSRegion);
-      mockAreasApi.getArea.mockResolvedValueOnce(londonNHSRegion);
+      mockGetSelectedAreasDataByAreaType.mockResolvedValue([
+        eastEnglandNHSRegion,
+        londonNHSRegion,
+      ]);
 
       const searchState: SearchStateParams = {
         ...searchParams,
         [SearchParams.IndicatorsSelected]: ['1', '2'],
+        [SearchParams.AreaTypeSelected]: 'nhs-regions',
         [SearchParams.AreasSelected]: ['E40000007', 'E40000003'],
       };
 
@@ -209,19 +214,9 @@ describe('Results Page', () => {
         searchParams: generateSearchParams(searchState),
       });
 
-      expect(mockAreasApi.getArea).toHaveBeenNthCalledWith(
-        1,
-        {
-          areaCode: eastEnglandNHSRegion.code,
-        },
-        API_CACHE_CONFIG
-      );
-      expect(mockAreasApi.getArea).toHaveBeenNthCalledWith(
-        2,
-        {
-          areaCode: londonNHSRegion.code,
-        },
-        API_CACHE_CONFIG
+      expect(mockGetSelectedAreasDataByAreaType).toHaveBeenCalledWith(
+        ['E40000007', 'E40000003'],
+        'nhs-regions'
       );
       expect(page.props.selectedAreasData).toEqual([
         eastEnglandNHSRegion,
diff --git a/frontend/fingertips-frontend/app/results/page.tsx b/frontend/fingertips-frontend/app/results/page.tsx
index 810c4cd5c..6ac1a8961 100644
--- a/frontend/fingertips-frontend/app/results/page.tsx
+++ b/frontend/fingertips-frontend/app/results/page.tsx
@@ -9,10 +9,8 @@ import { ErrorPage } from '@/components/pages/error';
 import { SearchServiceFactory } from '@/lib/search/searchServiceFactory';
 import { IndicatorSelectionState } from '@/components/forms/IndicatorSelectionForm/indicatorSelectionActions';
 import { getAreaFilterData } from '@/lib/areaFilterHelpers/getAreaFilterData';
-import {
-  API_CACHE_CONFIG,
-  ApiClientFactory,
-} from '@/lib/apiClient/apiClientFactory';
+import { getSelectedAreasDataByAreaType } from '@/lib/areaFilterHelpers/getSelectedAreasData';
+import { AreaTypeKeys } from '@/lib/areaFilterHelpers/areaType';
 import { areaCodeForEngland } from '@/lib/chartHelpers/constants';
 
 export default async function Page(
@@ -29,20 +27,15 @@ export default async function Page(
     [SearchParams.AreasSelected]: areasSelected,
     [SearchParams.IndicatorsSelected]: indicatorsSelected,
     [SearchParams.GroupSelected]: groupSelected,
+    [SearchParams.AreaTypeSelected]: areaTypeSelected,
   } = stateManager.getSearchState();
   try {
     await connection();
 
-    const areasApi = ApiClientFactory.getAreasApiClient();
-
-    const selectedAreasData =
-      areasSelected && areasSelected.length > 0
-        ? await Promise.all(
-            areasSelected.map((area) =>
-              areasApi.getArea({ areaCode: area }, API_CACHE_CONFIG)
-            )
-          )
-        : [];
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      areasSelected,
+      areaTypeSelected as AreaTypeKeys
+    );
 
     const {
       availableAreaTypes,
diff --git a/frontend/fingertips-frontend/components/forms/SearchForm/index.tsx b/frontend/fingertips-frontend/components/forms/SearchForm/index.tsx
index 45756f96a..1fc3f0562 100644
--- a/frontend/fingertips-frontend/components/forms/SearchForm/index.tsx
+++ b/frontend/fingertips-frontend/components/forms/SearchForm/index.tsx
@@ -8,7 +8,7 @@ import { AreaAutoCompleteInputField } from '@/components/molecules/AreaAutoCompl
 import { SearchParams } from '@/lib/searchStateManager';
 import { SearchFormState } from '@/components/forms/SearchForm/searchActions';
 import { SelectedAreasPanel } from '@/components/molecules/SelectedAreasPanel';
-import { AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import {
   AreaFilterData,
   SelectAreasFilterPanel,
@@ -25,7 +25,7 @@ const StyledInputField = styled(InputField)(
 
 interface SearchFormProps {
   formState: SearchFormState;
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   areaFilterData?: AreaFilterData;
 }
 
diff --git a/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/AreaSuggestionPanel.test.tsx b/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/AreaSuggestionPanel.test.tsx
index d2c1f8cca..14c682563 100644
--- a/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/AreaSuggestionPanel.test.tsx
+++ b/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/AreaSuggestionPanel.test.tsx
@@ -106,10 +106,11 @@ describe('AreaSuggestionPanel', () => {
     expect(container.firstChild).toBeNull();
   });
 
-  it('should update the url with the areaCode when a suggested area is clicked', async () => {
+  it('should update the url with the areaCode and areaType when a suggested area is clicked', async () => {
     const expectedPath = [
       `${mockPath}`,
       `?${SearchParams.AreasSelected}=GP01`,
+      `&${SearchParams.AreaTypeSelected}=gps`,
     ].join('');
 
     const user = userEvent.setup();
@@ -153,6 +154,7 @@ describe('AreaSuggestionPanel', () => {
     const expectedPath = [
       `${mockPath}`,
       `?${SearchParams.AreasSelected}=GP01`,
+      `&${SearchParams.AreaTypeSelected}=gps`,
     ].join('');
 
     const user = userEvent.setup();
diff --git a/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/index.tsx b/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/index.tsx
index 20e192648..62ba47bfc 100644
--- a/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/index.tsx
+++ b/frontend/fingertips-frontend/components/molecules/AreaSuggestionPanel/index.tsx
@@ -8,6 +8,10 @@ import { HighlightText } from '@/components/atoms/HighlightText';
 import { FOCUSABLE } from '@govuk-react/constants';
 import { useLoadingState } from '@/context/LoaderContext';
 import { useSearchState } from '@/context/SearchStateContext';
+import {
+  allAreaTypes,
+  englandAreaType,
+} from '@/lib/areaFilterHelpers/areaType';
 
 const StyleSearchSuggestionPanel = styled(UnorderedList)`
   display: flex;
@@ -63,19 +67,29 @@ export const AreaAutoCompleteSuggestionPanel = ({
   const pathname = usePathname();
   const router = useRouter();
 
-  const updateUrlWithSelectedArea = (selectedAreaCode: string | undefined) => {
+  const updateUrlWithSelectedArea = (
+    selectedAreaCode: string | undefined,
+    areaTypeSelected: string
+  ) => {
     setIsLoading(true);
 
+    const selectedAreaTypeKey =
+      allAreaTypes.find((areaType) => areaType.name === areaTypeSelected)
+        ?.key ?? englandAreaType.key;
+
     if (!selectedAreaCode) {
       stateManager.removeAllParamFromState(SearchParams.AreasSelected);
     } else {
-      stateManager.removeParamValueFromState(SearchParams.AreaTypeSelected);
       stateManager.removeParamValueFromState(SearchParams.GroupTypeSelected);
       stateManager.removeParamValueFromState(SearchParams.GroupSelected);
       stateManager.addParamValueToState(
         SearchParams.AreasSelected,
         selectedAreaCode
       );
+      stateManager.addParamValueToState(
+        SearchParams.AreaTypeSelected,
+        selectedAreaTypeKey
+      );
     }
     router.replace(stateManager.generatePath(pathname), { scroll: false });
   };
@@ -96,7 +110,7 @@ export const AreaAutoCompleteSuggestionPanel = ({
             data-testid={`area-suggestion-item-${area.areaCode}`}
             onClick={(e) => {
               e.preventDefault();
-              updateUrlWithSelectedArea(area.areaCode);
+              updateUrlWithSelectedArea(area.areaCode, area.areaType);
             }}
           >
             <SearchIcon
diff --git a/frontend/fingertips-frontend/components/molecules/SelectedAreasPanel/index.tsx b/frontend/fingertips-frontend/components/molecules/SelectedAreasPanel/index.tsx
index 3758c1e41..3beb7b3f1 100644
--- a/frontend/fingertips-frontend/components/molecules/SelectedAreasPanel/index.tsx
+++ b/frontend/fingertips-frontend/components/molecules/SelectedAreasPanel/index.tsx
@@ -1,4 +1,4 @@
-import { AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import { SearchParams, SearchStateManager } from '@/lib/searchStateManager';
 import { usePathname, useRouter } from 'next/navigation';
 import styled from 'styled-components';
@@ -12,7 +12,7 @@ import { useLoadingState } from '@/context/LoaderContext';
 import { useSearchState } from '@/context/SearchStateContext';
 
 interface SelectedAreasPanelProps {
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   areaFilterData?: AreaFilterData;
   isFullWidth?: boolean;
 }
diff --git a/frontend/fingertips-frontend/components/organisms/AreaFilterPane/index.tsx b/frontend/fingertips-frontend/components/organisms/AreaFilterPane/index.tsx
index 04ce65860..e9213c895 100644
--- a/frontend/fingertips-frontend/components/organisms/AreaFilterPane/index.tsx
+++ b/frontend/fingertips-frontend/components/organisms/AreaFilterPane/index.tsx
@@ -1,4 +1,4 @@
-import { AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import { H3, SectionBreak } from 'govuk-react';
 import styled from 'styled-components';
 import { ShowHideContainer } from '@/components/molecules/ShowHideContainer';
@@ -14,7 +14,7 @@ import { typography } from '@govuk-react/lib';
 import { GovukColours, TagColours } from '@/lib/styleHelpers/colours';
 
 interface AreaFilterPaneProps {
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   selectedIndicatorsData?: IndicatorDocument[];
   areaFilterData?: AreaFilterData;
   hideFilters?: () => void;
diff --git a/frontend/fingertips-frontend/components/pages/chartPageWrapper/index.tsx b/frontend/fingertips-frontend/components/pages/chartPageWrapper/index.tsx
index 01d4fffae..62e68a2b5 100644
--- a/frontend/fingertips-frontend/components/pages/chartPageWrapper/index.tsx
+++ b/frontend/fingertips-frontend/components/pages/chartPageWrapper/index.tsx
@@ -4,7 +4,7 @@ import { AreaFilterData } from '@/components/molecules/SelectAreasFilterPanel';
 import { AreaFilterPane } from '@/components/organisms/AreaFilterPane';
 import { useLoadingState } from '@/context/LoaderContext';
 import { useSearchState } from '@/context/SearchStateContext';
-import { AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import { IndicatorDocument } from '@/lib/search/searchTypes';
 import {
   SearchStateManager,
@@ -18,7 +18,7 @@ interface ChartPageWrapperProps {
   children: React.ReactNode;
   searchState?: SearchStateParams;
   areaFilterData?: AreaFilterData;
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   selectedIndicatorsData?: IndicatorDocument[];
 }
 
diff --git a/frontend/fingertips-frontend/components/pages/home/index.tsx b/frontend/fingertips-frontend/components/pages/home/index.tsx
index b4d9a8dba..d3cc1e74e 100644
--- a/frontend/fingertips-frontend/components/pages/home/index.tsx
+++ b/frontend/fingertips-frontend/components/pages/home/index.tsx
@@ -19,7 +19,7 @@ import {
 import { useActionState, useEffect } from 'react';
 import styled from 'styled-components';
 import { spacing } from '@govuk-react/lib';
-import { AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import { AreaFilterData } from '@/components/molecules/SelectAreasFilterPanel';
 import { useSearchState } from '@/context/SearchStateContext';
 
@@ -30,7 +30,7 @@ const ZeroMarginParagraph = styled(Paragraph)(
 interface HomeProps {
   searchState?: SearchStateParams;
   areaFilterData?: AreaFilterData;
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   initialFormState: SearchFormState;
 }
 export const Home = ({
diff --git a/frontend/fingertips-frontend/components/pages/results/index.tsx b/frontend/fingertips-frontend/components/pages/results/index.tsx
index 8bc42d303..1eff64d39 100644
--- a/frontend/fingertips-frontend/components/pages/results/index.tsx
+++ b/frontend/fingertips-frontend/components/pages/results/index.tsx
@@ -13,7 +13,7 @@ import {
 } from '@/lib/searchStateManager';
 import { AreaFilterPane } from '@/components/organisms/AreaFilterPane';
 import { IndicatorDocument } from '@/lib/search/searchTypes';
-import { AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import { IndicatorSearchForm } from '@/components/forms/IndicatorSearchForm';
 import {
   IndicatorSearchFormState,
@@ -29,7 +29,7 @@ type SearchResultsProps = {
   searchResults: IndicatorDocument[];
   areaFilterData?: AreaFilterData;
   isEnglandSelectedAsGroup: boolean;
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   searchState?: SearchStateParams;
   currentDate?: Date;
 };
diff --git a/frontend/fingertips-frontend/components/views/ViewsContext.tsx b/frontend/fingertips-frontend/components/views/ViewsContext.tsx
index 1357565f8..df1bfdb50 100644
--- a/frontend/fingertips-frontend/components/views/ViewsContext.tsx
+++ b/frontend/fingertips-frontend/components/views/ViewsContext.tsx
@@ -8,7 +8,7 @@ import { areaCodeForEngland } from '@/lib/chartHelpers/constants';
 
 import { AreaFilterData } from '../molecules/SelectAreasFilterPanel';
 import { ChartPageWrapper } from '../pages/chartPageWrapper';
-import { Area, AreaWithRelations } from '@/generated-sources/ft-api-client';
+import { Area } from '@/generated-sources/ft-api-client';
 import { IndicatorDocument } from '@/lib/search/searchTypes';
 import { ALL_AREAS_SELECTED } from '@/lib/areaFilterHelpers/constants';
 import { ViewsSelector } from './ViewsSelector';
@@ -37,7 +37,7 @@ const determineAreaCodes = (
 export type ViewProps = {
   searchState: SearchStateParams;
   areaFilterData?: AreaFilterData;
-  selectedAreasData?: AreaWithRelations[];
+  selectedAreasData?: Area[];
   selectedIndicatorsData?: IndicatorDocument[];
 };
 
diff --git a/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/AreasApi.ts b/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/AreasApi.ts
index f9019b13b..04a072738 100644
--- a/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/AreasApi.ts
+++ b/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/AreasApi.ts
@@ -145,7 +145,7 @@ export interface AreasApiInterface {
     getAreaTypes(requestParameters: GetAreaTypesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Array<AreaType>>;
 
     /**
-     * Get the basic details without children, parent relationships etc. for 1 or more areas
+     * Get the basic details without children, parent relationships etc. for 1 or more areas. Will return duplicate of areas that are applicable to multiple areaTypes.
      * @summary Get multiple areas
      * @param {Array<string>} [areaCodes] A list of area codes, up to 100 area codes can be requested
      * @param {*} [options] Override http request option.
@@ -155,7 +155,7 @@ export interface AreasApiInterface {
     getAreasRaw(requestParameters: GetAreasRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<Area>>>;
 
     /**
-     * Get the basic details without children, parent relationships etc. for 1 or more areas
+     * Get the basic details without children, parent relationships etc. for 1 or more areas. Will return duplicate of areas that are applicable to multiple areaTypes.
      * Get multiple areas
      */
     getAreas(requestParameters: GetAreasRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Array<Area>>;
@@ -338,7 +338,7 @@ export class AreasApi extends runtime.BaseAPI implements AreasApiInterface {
     }
 
     /**
-     * Get the basic details without children, parent relationships etc. for 1 or more areas
+     * Get the basic details without children, parent relationships etc. for 1 or more areas. Will return duplicate of areas that are applicable to multiple areaTypes.
      * Get multiple areas
      */
     async getAreasRaw(requestParameters: GetAreasRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<Area>>> {
@@ -361,7 +361,7 @@ export class AreasApi extends runtime.BaseAPI implements AreasApiInterface {
     }
 
     /**
-     * Get the basic details without children, parent relationships etc. for 1 or more areas
+     * Get the basic details without children, parent relationships etc. for 1 or more areas. Will return duplicate of areas that are applicable to multiple areaTypes.
      * Get multiple areas
      */
     async getAreas(requestParameters: GetAreasRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Array<Area>> {
diff --git a/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/IndicatorsApi.ts b/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/IndicatorsApi.ts
index c890478da..45ccc7e37 100644
--- a/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/IndicatorsApi.ts
+++ b/frontend/fingertips-frontend/generated-sources/ft-api-client/apis/IndicatorsApi.ts
@@ -120,7 +120,7 @@ export interface IndicatorsApiInterface {
     getIndicator(requestParameters: GetIndicatorRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Indicator>;
 
     /**
-     * Get quartile information for indicators including  
+     * Get quartile information for indicators including 
      * @summary Get quartile values for indicators
      * @param {string} areaCode The area code of the area/ geography
      * @param {string} ancestorCode The area code of an ancestor area
@@ -133,7 +133,7 @@ export interface IndicatorsApiInterface {
     indicatorsQuartilesGetRaw(requestParameters: IndicatorsQuartilesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<QuartileData>>>;
 
     /**
-     * Get quartile information for indicators including  
+     * Get quartile information for indicators including 
      * Get quartile values for indicators
      */
     indicatorsQuartilesGet(requestParameters: IndicatorsQuartilesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Array<QuartileData>>;
@@ -264,7 +264,7 @@ export class IndicatorsApi extends runtime.BaseAPI implements IndicatorsApiInter
     }
 
     /**
-     * Get quartile information for indicators including  
+     * Get quartile information for indicators including 
      * Get quartile values for indicators
      */
     async indicatorsQuartilesGetRaw(requestParameters: IndicatorsQuartilesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Array<QuartileData>>> {
@@ -305,7 +305,7 @@ export class IndicatorsApi extends runtime.BaseAPI implements IndicatorsApiInter
     }
 
     /**
-     * Get quartile information for indicators including  
+     * Get quartile information for indicators including 
      * Get quartile values for indicators
      */
     async indicatorsQuartilesGet(requestParameters: IndicatorsQuartilesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Array<QuartileData>> {
diff --git a/frontend/fingertips-frontend/lib/areaFilterHelpers/getAreaFilterData.ts b/frontend/fingertips-frontend/lib/areaFilterHelpers/getAreaFilterData.ts
index c4c5a1526..9cdc6e433 100644
--- a/frontend/fingertips-frontend/lib/areaFilterHelpers/getAreaFilterData.ts
+++ b/frontend/fingertips-frontend/lib/areaFilterHelpers/getAreaFilterData.ts
@@ -30,7 +30,7 @@ type AreaFilterData = {
 
 export const getAreaFilterData = async (
   searchState: SearchStateParams,
-  selectedAreasData?: AreaWithRelations[]
+  selectedAreasData?: Area[]
 ): Promise<AreaFilterData> => {
   const stateManager = SearchStateManager.initialise(searchState);
 
diff --git a/frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx b/frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
new file mode 100644
index 000000000..7c4134ecf
--- /dev/null
+++ b/frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
@@ -0,0 +1,117 @@
+import { mockDeep } from 'jest-mock-extended';
+import { AreaTypeKeys, englandAreaType, nhsRegionsAreaType } from './areaType';
+import { getSelectedAreasDataByAreaType } from './getSelectedAreasData';
+import { Area, AreasApi } from '@/generated-sources/ft-api-client';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+const mockAreasApi = mockDeep<AreasApi>();
+ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+
+const generateMockArea = (
+  areaCode: string,
+  areaTypeKey: AreaTypeKeys
+): Area => ({
+  code: areaCode,
+  name: `name-${areaCode}`,
+  areaType: {
+    key: areaTypeKey,
+    name: 'some name',
+    level: 2,
+    hierarchyName: 'NHS',
+  },
+});
+
+describe('getSelectedAreasDataByAreaType', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should return an empty array when areas selected is undefined', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      undefined,
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an empty array when areas selected is an empty array', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      [],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an array of selectedAreasData returned from the API for the selected areas provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A003', 'nhs-regions');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002', 'A003'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002', 'A003'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2, area3]);
+  });
+
+  it('should return an array of selectedAreasData and filter out areas that do not match the areaType provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A001', 'nhs-primary-care-networks');
+    const area4 = generateMockArea('A002', 'nhs-primary-care-networks');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3, area4]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2]);
+  });
+
+  it('should throw an error if no areaData is found for any of the areaSelected', async () => {
+    mockAreasApi.getAreas.mockResolvedValue([]);
+
+    await expect(
+      async () => await getSelectedAreasDataByAreaType(['A001', 'A002'])
+    ).rejects.toThrow('No area data found for any of the areas selected');
+  });
+
+  it('should return the selectedAreaData of the areas that were found', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    mockAreasApi.getAreas.mockResolvedValue([area1]);
+
+    const selectedAreaData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002'],
+      'nhs-regions'
+    );
+
+    expect(selectedAreaData).toEqual([area1]);
+  });
+
+  it('should default to filtering by england areaType when areaTypeSelected in not provided', async () => {
+    const area1 = generateMockArea('A001', englandAreaType.key as AreaTypeKeys);
+    mockAreasApi.getAreas.mockResolvedValue([area1]);
+
+    const selectedAreaData = await getSelectedAreasDataByAreaType(['A001']);
+
+    expect(selectedAreaData).toEqual([area1]);
+  });
+});
diff --git a/frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts b/frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
new file mode 100644
index 000000000..f2ec80014
--- /dev/null
+++ b/frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
@@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
+      : [];
+
+  if (
+    areasSelected &&
+    areasSelected.length > 0 &&
+    selectedAreasData.length === 0
+  ) {
+    throw new Error('No area data found for any of the areas selected');
+  }
+
+  return selectedAreasData;
+};
diff --git a/frontend/fingertips-frontend/mock/server/handlers.ts b/frontend/fingertips-frontend/mock/server/handlers.ts
index b6d8786b7..4047c6388 100644
--- a/frontend/fingertips-frontend/mock/server/handlers.ts
+++ b/frontend/fingertips-frontend/mock/server/handlers.ts
@@ -7,6 +7,7 @@ import {
   AreaTypeKeys,
 } from '../../lib/areaFilterHelpers/areaType';
 import {
+  Area,
   AreaWithRelations,
   BenchmarkComparisonMethod,
   IndicatorWithHealthDataForArea,
@@ -84,6 +85,19 @@ export const handlers = [
 
     return HttpResponse.json(...resultArray[next() % resultArray.length]);
   }),
+  http.get(`${baseURL}/areas`, async ({ request }) => {
+    const url = new URL(request.url);
+    const areaCodes = url.searchParams.getAll('area_codes') ?? [];
+
+    const selectedAreaData = getMockSelectedAreaData(areaCodes);
+    if (selectedAreaData.length === 0) {
+      return HttpResponse.json(
+        { error: 'No area data found for selected areas' },
+        { status: 404 }
+      );
+    }
+    return HttpResponse.json(selectedAreaData, { status: 200 });
+  }),
   http.get(`${baseURL}/indicators`, async () => {
     const resultArray = [[getFilterIndicators200Response(), { status: 200 }]];
 
@@ -242,3 +256,17 @@ export function getGetHealthDataForAnIndicator200Response(
 function isAreaCodesEmpty(areaCodes: string[]) {
   return !areaCodes.length || (areaCodes.length === 1 && areaCodes[0] === '');
 }
+
+function getMockSelectedAreaData(areaCodes: string[]) {
+  const mockDataForAreas: Area[] = [];
+
+  areaCodes.forEach((areaCode) => {
+    if (mockAreaData[areaCode]) {
+      mockDataForAreas.push(mockAreaData[areaCode] as Area);
+    }
+  });
+
+  return mockDataForAreas.filter(
+    (mockArea) => !mockArea.code.toLowerCase().includes('error')
+  );
+}
diff --git a/frontend/fingertips-frontend/playwright/page-objects/pages/resultsPage.ts b/frontend/fingertips-frontend/playwright/page-objects/pages/resultsPage.ts
index 797df01fc..614792568 100644
--- a/frontend/fingertips-frontend/playwright/page-objects/pages/resultsPage.ts
+++ b/frontend/fingertips-frontend/playwright/page-objects/pages/resultsPage.ts
@@ -8,6 +8,10 @@ import {
 } from '@/playwright/testHelpers';
 import AreaFilter from '../components/areaFilter';
 import { RawIndicatorDocument } from '@/lib/search/searchTypes';
+import {
+  AreaTypeKeys,
+  englandAreaType,
+} from '@/lib/areaFilterHelpers/areaType';
 
 export default class ResultsPage extends AreaFilter {
   readonly resultsText = 'Search results';
@@ -34,7 +38,8 @@ export default class ResultsPage extends AreaFilter {
 
   async navigateToResults(
     searchIndicator: string,
-    selectedAreaCodes: string[]
+    selectedAreaCodes: string[],
+    selectedAreaType?: AreaTypeKeys
   ) {
     const asQuery = selectedAreaCodes.reduce(
       (accumulator, currentValue) =>
@@ -42,8 +47,10 @@ export default class ResultsPage extends AreaFilter {
       ''
     );
 
+    const determineAreaTypeSelected = selectedAreaType ?? englandAreaType.key;
+
     await this.page.goto(
-      `results?${SearchParams.SearchedIndicator}=${searchIndicator}${asQuery}`
+      `results?${SearchParams.SearchedIndicator}=${searchIndicator}&${SearchParams.AreaTypeSelected}=${determineAreaTypeSelected}${asQuery}`
     );
   }
 
diff --git a/frontend/fingertips-frontend/playwright/tests/isolated_ui_tests/navigation_and_validation.spec.ts b/frontend/fingertips-frontend/playwright/tests/isolated_ui_tests/navigation_and_validation.spec.ts
index 94eaa356c..9295c0853 100644
--- a/frontend/fingertips-frontend/playwright/tests/isolated_ui_tests/navigation_and_validation.spec.ts
+++ b/frontend/fingertips-frontend/playwright/tests/isolated_ui_tests/navigation_and_validation.spec.ts
@@ -172,11 +172,15 @@ test.describe(`Navigation, accessibility and validation tests`, () => {
     resultsPage,
   }) => {
     await test.step('Navigate directly to the results page', async () => {
-      await resultsPage.navigateToResults(subjectSearchTerm, [
-        allNHSRegionAreas[0].areaCode,
-        allNHSRegionAreas[1].areaCode,
-        allNHSRegionAreas[2].areaCode,
-      ]);
+      await resultsPage.navigateToResults(
+        subjectSearchTerm,
+        [
+          allNHSRegionAreas[0].areaCode,
+          allNHSRegionAreas[1].areaCode,
+          allNHSRegionAreas[2].areaCode,
+        ],
+        'nhs-regions'
+      );
     });
 
     await test.step('Check selected area pills matches those specified in url', async () => {
@@ -244,11 +248,15 @@ test.describe(`Navigation, accessibility and validation tests`, () => {
     resultsPage,
   }) => {
     await test.step('Navigate directly to the results page', async () => {
-      await resultsPage.navigateToResults(subjectSearchTerm, [
-        allNHSRegionAreas[0].areaCode,
-        allNHSRegionAreas[1].areaCode,
-        allNHSRegionAreas[2].areaCode,
-      ]);
+      await resultsPage.navigateToResults(
+        subjectSearchTerm,
+        [
+          allNHSRegionAreas[0].areaCode,
+          allNHSRegionAreas[1].areaCode,
+          allNHSRegionAreas[2].areaCode,
+        ],
+        'nhs-regions'
+      );
     });
 
     await test.step('Select single indicator, and verify url is updated to include indicator', async () => {


Reviews:
user: login: williamwillis11
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T16:02:55Z
user: login: stuc-bjss
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T16:24:27Z
user: login: alibombaye
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T16:29:23Z
user: login: dlzhry2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T08:15:42Z
user: login: dlzhry2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T08:26:11Z
user: login: dlzhry2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T08:30:26Z
user: login: dlzhry2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T08:31:30Z
user: login: dlzhry2
body: Looks really good to me. Happy to approve after quick discussion - just a minor comment raised regarding 404 scenario.
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T08:32:25Z
user: login: alibombaye
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T09:14:13Z
user: login: alibombaye
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T09:17:49Z
user: login: dlzhry2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T09:20:55Z
user: login: dlzhry2
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T09:21:53Z
user: login: alibombaye
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T09:26:10Z
user: login: dlzhry2
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T09:48:34Z
user: login: dlzhry2
body: Looks good
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-07T12:46:17Z

Review comments:
diff_hunk: @@ -0,0 +1,117 @@
+import { mockDeep } from 'jest-mock-extended';
+import { AreaTypeKeys, englandAreaType, nhsRegionsAreaType } from './areaType';
+import { getSelectedAreasDataByAreaType } from './getSelectedAreasData';
+import { Area, AreasApi } from '@/generated-sources/ft-api-client';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+const mockAreasApi = mockDeep<AreasApi>();
+ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+
+const generateMockArea = (
+  areaCode: string,
+  areaTypeKey: AreaTypeKeys
+): Area => ({
+  code: areaCode,
+  name: `name-${areaCode}`,
+  areaType: {
+    key: areaTypeKey,
+    name: 'some name',
+    level: 2,
+    hierarchyName: 'NHS',
+  },
+});
+
+describe('getSelectedAreasDataByAreaType', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should return an empty array when areas selected is undefined', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      undefined,
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an empty array when areas selected is an empty array', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      [],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an array of selectedAreasData returned from the API for the selected areas provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A003', 'nhs-regions');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002', 'A003'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002', 'A003'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2, area3]);
+  });
+
+  it('should return an array of selectedAreasData and filter out areas that do not match the areaType provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A001', 'nhs-primary-care-networks');
+    const area4 = generateMockArea('A002', 'nhs-primary-care-networks');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3, area4]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2]);
+  });
+
+  it('should throw an error if no areaData is found for any of the areaSelected', async () => {
+    mockAreasApi.getAreas.mockResolvedValue([]);
+
+    await expect(
+      async () => await getSelectedAreasDataByAreaType(['A001', 'A002'])
+    ).rejects.toThrow('No area data found for any of the areas selected');
+  });
+
+  it('should return the selectedAreaData of the areas that were found', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    mockAreasApi.getAreas.mockResolvedValue([area1]);
+
+    const selectedAreaData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002'],
+      'nhs-regions'
+    );
+
+    expect(selectedAreaData).toEqual([area1]);
+  });
+
+  it('should default to filtering by england areaType when areaTypeSelected in not provided', async () => {
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
user: login: williamwillis11
body: is not provided
created_at: 2025-04-04T16:02:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: stuc-bjss
body: any chance we can do this filtering in the api to avoid passing data we don't need into nextjs
created_at: 2025-04-04T16:24:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: alibombaye
body: Yeah good point. Myself and @dlzhry2 had this discussion this morning on exactly this and believed it was the correct thing for the api to just return all the areas and let the FE then decide what it needed. 
created_at: 2025-04-04T16:29:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: dlzhry2
body: Yup, the existing endpoint: `/areas/{area_code}` it turns out is not actually idempotent. It just returns the first result it gets, which could be either.

Only applies to some areas which fall into both districts and counties. Ultimately not a problem with the existing endpoint, as the UI knows which area type has been requested and when calling health measures we pass the area code and filter on area type if relevant.

Fawad has dropped a clarification for how this works in the Swagger. But could potentially extend this new endpoint (and perhaps the existing one) to also allow filtering for area type, so you can get one rather than two results back for certain area codes.
created_at: 2025-04-07T08:15:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
+      : [];
+
+  if (
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: dlzhry2
body: Not sure if we have custom behaviour for the generated client, so maybe we would get to this point. But if a area code/set of codes returns nothing, then you get a 404 error. See: `api/DHSC.FingertipsNext.Modules.Area/HttpClientScripts/test-areas-multiple-areas.http`

Would we want to catch the API call and logs out an error message plus the contents of the API error?
created_at: 2025-04-07T08:26:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,117 @@
+import { mockDeep } from 'jest-mock-extended';
+import { AreaTypeKeys, englandAreaType, nhsRegionsAreaType } from './areaType';
+import { getSelectedAreasDataByAreaType } from './getSelectedAreasData';
+import { Area, AreasApi } from '@/generated-sources/ft-api-client';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+const mockAreasApi = mockDeep<AreasApi>();
+ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+
+const generateMockArea = (
+  areaCode: string,
+  areaTypeKey: AreaTypeKeys
+): Area => ({
+  code: areaCode,
+  name: `name-${areaCode}`,
+  areaType: {
+    key: areaTypeKey,
+    name: 'some name',
+    level: 2,
+    hierarchyName: 'NHS',
+  },
+});
+
+describe('getSelectedAreasDataByAreaType', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should return an empty array when areas selected is undefined', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      undefined,
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an empty array when areas selected is an empty array', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      [],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an array of selectedAreasData returned from the API for the selected areas provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A003', 'nhs-regions');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002', 'A003'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002', 'A003'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2, area3]);
+  });
+
+  it('should return an array of selectedAreasData and filter out areas that do not match the areaType provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
user: login: dlzhry2
body: Minor as it's test data, but I think the only area codes that can belong to both are districts + counties and unitary authorities. Apologies if I'm wrong. But was thinking if that's the only scenario, it could be useful for the scenario to align so it's a bit more descriptive and helpful to whoever picks this project up next.
created_at: 2025-04-07T08:30:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,117 @@
+import { mockDeep } from 'jest-mock-extended';
+import { AreaTypeKeys, englandAreaType, nhsRegionsAreaType } from './areaType';
+import { getSelectedAreasDataByAreaType } from './getSelectedAreasData';
+import { Area, AreasApi } from '@/generated-sources/ft-api-client';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+const mockAreasApi = mockDeep<AreasApi>();
+ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+
+const generateMockArea = (
+  areaCode: string,
+  areaTypeKey: AreaTypeKeys
+): Area => ({
+  code: areaCode,
+  name: `name-${areaCode}`,
+  areaType: {
+    key: areaTypeKey,
+    name: 'some name',
+    level: 2,
+    hierarchyName: 'NHS',
+  },
+});
+
+describe('getSelectedAreasDataByAreaType', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should return an empty array when areas selected is undefined', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      undefined,
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an empty array when areas selected is an empty array', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      [],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an array of selectedAreasData returned from the API for the selected areas provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A003', 'nhs-regions');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002', 'A003'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002', 'A003'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2, area3]);
+  });
+
+  it('should return an array of selectedAreasData and filter out areas that do not match the areaType provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A001', 'nhs-primary-care-networks');
+    const area4 = generateMockArea('A002', 'nhs-primary-care-networks');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3, area4]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2]);
+  });
+
+  it('should throw an error if no areaData is found for any of the areaSelected', async () => {
+    mockAreasApi.getAreas.mockResolvedValue([]);
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
user: login: dlzhry2
body: I don't think the API will resolve to this with a 200.
created_at: 2025-04-07T08:31:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
+      : [];
+
+  if (
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: alibombaye
body: ah ok so we would never get a situation where we get an empty array back if not area data is found and just a 404. All these calls on the pages are surrounded by try catch blocks that already log the error and show the error page. I just need to remove these checks and let the error bubble up.
created_at: 2025-04-07T09:14:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,117 @@
+import { mockDeep } from 'jest-mock-extended';
+import { AreaTypeKeys, englandAreaType, nhsRegionsAreaType } from './areaType';
+import { getSelectedAreasDataByAreaType } from './getSelectedAreasData';
+import { Area, AreasApi } from '@/generated-sources/ft-api-client';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+const mockAreasApi = mockDeep<AreasApi>();
+ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+
+const generateMockArea = (
+  areaCode: string,
+  areaTypeKey: AreaTypeKeys
+): Area => ({
+  code: areaCode,
+  name: `name-${areaCode}`,
+  areaType: {
+    key: areaTypeKey,
+    name: 'some name',
+    level: 2,
+    hierarchyName: 'NHS',
+  },
+});
+
+describe('getSelectedAreasDataByAreaType', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should return an empty array when areas selected is undefined', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      undefined,
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an empty array when areas selected is an empty array', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      [],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an array of selectedAreasData returned from the API for the selected areas provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A003', 'nhs-regions');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002', 'A003'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002', 'A003'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2, area3]);
+  });
+
+  it('should return an array of selectedAreasData and filter out areas that do not match the areaType provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
user: login: alibombaye
body: The function in general has no context about the the area-types that cause this. Since this can change in the future or more could be added and the test description is no longer valid. But I do think it's something that belongs in more of the e2e tests since it a particular behaviour related to the data we get back. I'll have a chat with @williamwillis11 about potentially adding something there.
created_at: 2025-04-07T09:17:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,117 @@
+import { mockDeep } from 'jest-mock-extended';
+import { AreaTypeKeys, englandAreaType, nhsRegionsAreaType } from './areaType';
+import { getSelectedAreasDataByAreaType } from './getSelectedAreasData';
+import { Area, AreasApi } from '@/generated-sources/ft-api-client';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+const mockAreasApi = mockDeep<AreasApi>();
+ApiClientFactory.getAreasApiClient = () => mockAreasApi;
+
+const generateMockArea = (
+  areaCode: string,
+  areaTypeKey: AreaTypeKeys
+): Area => ({
+  code: areaCode,
+  name: `name-${areaCode}`,
+  areaType: {
+    key: areaTypeKey,
+    name: 'some name',
+    level: 2,
+    hierarchyName: 'NHS',
+  },
+});
+
+describe('getSelectedAreasDataByAreaType', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should return an empty array when areas selected is undefined', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      undefined,
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an empty array when areas selected is an empty array', async () => {
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      [],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(selectedAreasData).toEqual([]);
+  });
+
+  it('should return an array of selectedAreasData returned from the API for the selected areas provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
+    const area2 = generateMockArea('A002', 'nhs-regions');
+    const area3 = generateMockArea('A003', 'nhs-regions');
+
+    mockAreasApi.getAreas.mockResolvedValue([area1, area2, area3]);
+
+    const selectedAreasData = await getSelectedAreasDataByAreaType(
+      ['A001', 'A002', 'A003'],
+      nhsRegionsAreaType.key as AreaTypeKeys
+    );
+
+    expect(mockAreasApi.getAreas).toHaveBeenCalledWith(
+      { areaCodes: ['A001', 'A002', 'A003'] },
+      API_CACHE_CONFIG
+    );
+    expect(selectedAreasData).toEqual([area1, area2, area3]);
+  });
+
+  it('should return an array of selectedAreasData and filter out areas that do not match the areaType provided', async () => {
+    const area1 = generateMockArea('A001', 'nhs-regions');
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.test.tsx
user: login: dlzhry2
body: Sounds good.
created_at: 2025-04-07T09:20:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
+      : [];
+
+  if (
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: dlzhry2
body: Correct, if no data is found you will get the 404 error code. Perfect, that sounds good. Imagined we'd have some global/higher level handling or interceptors.
created_at: 2025-04-07T09:21:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,37 @@
+import { Area } from '@/generated-sources/ft-api-client';
+import { AreaTypeKeys, englandAreaType } from './areaType';
+import {
+  API_CACHE_CONFIG,
+  ApiClientFactory,
+} from '@/lib/apiClient/apiClientFactory';
+
+export const getSelectedAreasDataByAreaType = async (
+  areasSelected?: string[],
+  areaTypeSelected?: AreaTypeKeys
+): Promise<Area[]> => {
+  const areasApi = ApiClientFactory.getAreasApiClient();
+
+  const determineAreaTypeSelected = areaTypeSelected ?? englandAreaType.key;
+
+  const selectedAreasData =
+    areasSelected && areasSelected?.length > 0
+      ? (
+          await areasApi.getAreas(
+            {
+              areaCodes: areasSelected ?? [],
+            },
+            API_CACHE_CONFIG
+          )
+        ).filter((area) => area.areaType.key === determineAreaTypeSelected)
+      : [];
+
+  if (
path: frontend/fingertips-frontend/lib/areaFilterHelpers/getSelectedAreasData.ts
user: login: alibombaye
body: check removed 
created_at: 2025-04-07T09:26:10Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-04-07T13:09:37Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=dhsc-govuk_FingertipsNext&pullRequest=404) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=dhsc-govuk_FingertipsNext&pullRequest=404&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=dhsc-govuk_FingertipsNext&pullRequest=404&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=dhsc-govuk_FingertipsNext&pullRequest=404&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=dhsc-govuk_FingertipsNext&pullRequest=404&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=dhsc-govuk_FingertipsNext&pullRequest=404&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=dhsc-govuk_FingertipsNext&pullRequest=404)


author_association: NONE