This project implements Address Options Mocking using MSW (Mock Service Worker) to simulate API responses for address selection. It enables seamless testing and development by providing mocked address suggestions, handling user inputs, and simulating dynamic API behavior.
First, let’s speak about the use case. I’ll demonstrate how we can implement address dropdown choices without using a real server by establishing a fake server on the client side (in the browser).
First and foremost, I have previously published a blog on the issue. Essentially, the browser performs rendering activities in a single process and event loop. We utilize Web Worker or its specialized version Service Worker for performance (for example, background computation on the map) or other mimicking actions that we want to do concurrently. MSW is a mock creation tool built with this Service Worker.
In our first example Address Form [Demo], our goal is to create an environment where the Dropdown components and its content are fixed.
First, we write our components. We create the Province, District, and Neighborhood Dropdowns.
const renderDemo = () => {
const districtArr = districts.filter((el) => el.value.includes(selectedCity));
const neighborhoodArr = neighborhoods.filter((el) =>
el.value.includes(selectedDistrict)
);
return (
<div style={{ display: "flex", gap: "3px", alignItems: "center" }}>
<Typography.Text strong>Address Form</Typography.Text>
<Select
style={{ width: 150 }}
options={cities}
onChange={onCityChange}
optionLabel="name"
placeholder="Il Sec"
/>
<Select
style={{ width: 150 }}
options={districtArr}
onChange={onDistrictChange}
optionLabel="name"
placeholder="Ilce Sec"
/>
<Select
style={{ width: 150 }}
options={neighborhoodArr}
onChange={onNeighborhoodChange}
optionLabel="name"
placeholder="Mahalle Sec"
/>
<Button type="primary" onClick={handleApply}>
Submit
</Button>
</div>
);
};
The next thing is to create the content within it.
export const neighborhoods = [
{ label: "Beşiktaş_Mahalle1", value: "IST_BSK_MH1" },
{ label: "Beşiktaş_Mahalle2", value: "IST_BSK_MH2" },
{ label: "Kadıköy_Mahalle1", value: "IST_KAD_MH1" },
{ label: "Kadıköy_Mahalle2", value: "IST_KAD_MH2" },
{ label: "Beyoğlu_Mahalle1", value: "IST_BEY_MH1" },
{ label: "Beyoğlu_Mahalle2", value: "IST_BEY_MH2" },
{ label: "Çankaya_Mahalle1", value: "ANK_CANK_MH1" },
{ label: "Çankaya_Mahalle2", value: "ANK_CANK_MH2" },
{ label: "Keçiören_Mahalle1", value: "ANK_KEC_MH1" },
{ label: "Keçiören_Mahalle2", value: "ANK_KEC_MH2" },
{ label: "Yenimahalle_Mahalle1", value: "ANK_YNM_MH1" },
{ label: "Yenimahalle_Mahalle2", value: "ANK_YNM_MH2" },
];
export const districts = [
{ label: "Beşiktaş", value: "IST_BSK" },
{ label: "Kadıköy", value: "IST_KAD" },
{ label: "Beyoğlu", value: "IST_BEY" },
{ label: "Çankaya", value: "ANK_CANK" },
{ label: "Keçiören", value: "ANK_KEC" },
{ label: "Yenimahalle", value: "ANK_YNM" },
];
export const cities = [
{ label: "Istanbul", value: "IST" },
{ label: "Ankara", value: "ANK" },
];
We have now produced static mockdata. When we pass this data straight to the components as props, we generate a simple mock.
In the second example, we’d want to complicate matters even further by using a real server and a retrieve request. In other words, a request will be issued from the network layer, returned from the server, and the dropdowns will be updated accordingly.
What are the benefits of having an MSW?
Let us now look at the Address Fetch [Demo] example. In this example, in the background, we turn the static data into an HTTP Callback Handler.
import { HttpResponse, http } from "msw";
export const restApiUri = "https://api.onurdayibasi.dev";
export const cityHandlers = [
http.get(`${restApiUri}/address/cities`, async () => {
return HttpResponse.json(cities);
}),
http.get(`${restApiUri}/address/districts`, async () => {
return HttpResponse.json(districts);
}),
http.get(`${restApiUri}/address/neighborhoods`, async () => {
return HttpResponse.json(neighborhoods);
}),
];
After this handle operation, we assign it to MSW worker.
import { setupWorker } from "msw/browser";
import { cityHandlers } from "@garden/mocks/cityHandlers";
export const mockServerWorker = setupWorker(...cityHandlers);
Now we have a structure that can respond to the requests made through the server and respond to these requests.