While developing lwc components and lightning apps I always run into this design dilemma: When I have two children components that uses the same set of source data but in different forms what is the best practice when it comes retrieving data?
Here is an example situation that I run into recently:
I want do display a list of parcels for a city
Parent Component:
Child Component 1: a table view of the parcels which display all the parcels in columns. columns are defined based on a list view fields.
Child Component 2: a map view that plotted the parcels on the map based on its geo-location. And also display a summary of the parcel object. the summary is also generated based on the same list view fields.
Child Component 1 need know a list of parcel and fields from a list view and convert them into table data format.
Child Component 2 need to know the same list of parcel and list view and convert them into mapviewer data format.
My struggling is to find a best practice to sufficiently retrieve the data. and scalable way to transform the data so that the two children component are not coupled and they can be used independently in the future.
Approach 1: Child Component 1 and Child Component 2 are developed separately and they are self-contained. So CC1 and CC2 have their own apex controllers and wiring functions. The controllers uses the same Apex DataService to retrieve required information: parcels and list view. The controllers uses their own data converter to convert parcels and listview in to the data format required by UI(like DataTableVO and MapFeatureVO). And these data modules are returned to the client for the use of UI display.
Advantages:
- the child components are highly decouple
- DataTableVO and MapFeatureVO are in the apex code, it is easily to exposes these classes for global use and increased the readability of the code. Consumers knows how to implements a convertor for these data type increase the exdtenbilty of these component
Disadvantages:
- When we integrate two component together, since they are not binds to same datasource on the UI it is hard to sync data between two component. One change on CC1 cannot reflect on CC2 via data binding.
- Since the data convertor is in Apex when new data(say a new parcel) is added via UI, client logic cannot do the conversion it always need to go back to Apex to refresh data
- too many duplicate and inefficient web calls. (ex. retrieving same data set two times when parent component is loaded).
Approach 2: Child Component 1 and Child Component 2 requires Higher Order Component to feed the data they need. And data are passed on as @api properties. Parent Component retrieves required data(parcels and list view info) via apex wire. Have javascript helper functions to convert data into the format that subcomponents needs. After data has been parsed and converted set the binding @api properties on sub components and make them render.
Advantages:
- Child components are almost pure ui component more extendable.
- Data management are more centralized. easy to handle data sync via parent component and data binding
- Efficient in terms of web calls.
- More logics on the client side and the data convertors are close to where the data is consumed(Sub component).
Disadvantages:
- Child component is not self-contained. You always need to provider a higher order components when you try to use the child component.
- DataModel VO and converter is in javascript and it is not type safe. Decreasing the readability of the code(maybe)?