React Best Practice to bind checkbox to model - reactjs

I'm new to React and I'm having a little trouble to come up with the 'right' way to handle the following situation:
So let's say I'm fetching entities from a backend that contain a boolean value. And I want to show that entities in a React component using a Material UI checkbox. Now when the user checks or unchecks the checkbox I want to update the corresponding entity in the backend immediately.
Pretty simple I thought. So my first approach was to use UseQuery to fetch the data:
const res = await axios.get<IResourceChange[]>(
`https://localhost:5001/api/configpicker/resourcechangecollections/${resourceChangeCollectionId}/resourceChanges`
);
return res.data;
};
const {
data: resourceChanges,
isLoading: isLoadingResourceChanges,
error: loadingResourceChangesError,
} = useQuery<IResourceChange[]>('resourceChanges', fetchResourceChanges);
And then I'm mapping that entities to checkboxes:
resourceChanges?.map((rc) => {
return (
<FormControlLabel
control={
<Checkbox
checked={rc.excludeFromExport}
onChange={() =>
handleCheckboxChange(
rc.resourceChangeID,
!rc.excludeFromExport
)
}
/>
}
label="Exclude from export"
/>
);
})
And handle the change by sending a PATCH request to the backend:
const handleCheckboxChange = (
resourceChangeId: number,
newChecked: boolean
) => {
axios
.patch(
`https://localhost:5001/api/configpicker/resourcechanges/${resourceChangeId}`,
[
{
op: 'replace',
path: '/excludeFromExport',
value: newChecked,
},
]
)
.then((res) => console.log('res :>> ', res));
};
I'm sure you experts can spot some problems with that. I have a few thoughts how to change this approach, but I couldn't find a guide on what's the best practice to do this.
I have a feeling, that I should replicate the checkbox value in the state, but that seems kind of redundant.
Is there a best practice how to implement this?

Related

React - Populate a select once with Apollo and filtering

I am currently struggling with react and GraphQL.
The following scenario:
I do have a GraphQL endpoint that basically returns me NuGet Feeds for a given spaceID (imagine this would be like your GitHub organization where you can have multiple repositories under it).
Under each feed, there can be 0 to n packages. As you might have a lot of repositories under one GitHub organization, some kind of filtering would be nice - in my case, a simple good old select.
The select should be populated with all possible repositories I retrieve in my response from my graphql call (Apollo). Under it, I just list all packages in all the feeds.
Now when a user clicks on one entry in the select, the list beneath obviously should only show nuget packages to that corresponding feed. Filtering the list on the client will not work, as a result is paged, so we have to go to the backend once more. (I will simplify that in code).
In simple terms I want to have the possible feeds in my select, even when a user selects one entry.
export function Nuget() {
const spaceId = getSpaceId();
const [selectedNugetFeed, setSelectedNugetFeed] = useState<NugetFeed | undefined>();
const [nugetFeeds, setNugetFeeds] = useState<NugetFeed[] | undefined>([]);
const handleScopeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
setSelectedNugetFeed(nugetFeeds!.find(d => d.scopeId == event.target.value))
};
const { loading, error, data } = useNugetFeedsByIdQuery({
variables: { spaceID: spaceId, scopeID: selectedNugetFeed?.scopeId },
});
useEffect(() => {
if (data) {
setNugetFeeds(data.nugetFeeds);
}
}, [spaceId]);
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return (<p>Error</p>);
}
const options = nugetFeeds!.map(r => ({ value: r.scopeId, label: r.scope }));
return (
<>
<div className='flex justify-end'>
<Select
placeholder="Filter scope"
name="nuget-artifact-scope"
value={selectedNugetFeed?.scopeId}
options={options}
onChange={handleScopeChange}
className="w-1/6"
/>
</div>
{data?.nugetFeeds
.flatMap(r => r.packages
.map(s => (
<HereWillBePackages></HereWillBePackages>
)))}
</>
);
}
Just as a quick explanation: Space would be a github organization and scopeId the ID from the repository that is under such organization. Scope itself would be the name.
This approach has some downsides. First of all, the list doesn't get populated all the times. The second reason, once we click on a select, I still want all possible "scopes" in my select.
Is there any good way to do so with only one backend call?

How can I make transient/one-off state changes to a React component from one of its ancestors?

I want to modify the state of a child component in React from a parent component a couple levels above it.
The child component is a react-table with pagination.
My use case is changing the data in the table with some client-side JS filtering.
The problem is, the table uses internal state to keep track of which page is being shown, and does not fully update in response to my filtering.
It is smart enough to know how much data it contains, but not smart enough to update the page it is on.
So, it might correctly say "Showing items 21-30 of 85", and then the user filters the data down to only four total items, and the table will say "Showing items 21-30 of 4".
I tried implementing something like what the FAQ suggests for manual state control, but that caused its own problem.
I was passing the new page index in as a prop, and that did set the page correctly, but it broke the ability for the user to navigate between pages, because any changes were immediately overwritten by the value of the prop.
Those instructions seem to work for a situation where all page index control gets handled by the parent, but not when some control should still be retained by the pagination mechanism.
I think what I need is an exposed function that lets me modify the value of the table's state.pageIndex as a one-off instead of passing a permanent prop. Is there a way to do that? Or any other way to solve my underlying problem?
Code follows. I apologize in advance I couldn't make this a real SSCCE, it was just too complicated, I tried to at least follow the spirit of SSCCEs as much as I could.
My page that lists stuff for the user looks like this:
// ...
const [searchTerms, setSearchTerms] = useState<Array<string>>([]);
// ...
const handleFilterRequestFromUser = function (searchTerms): void {
// ...
setSearchTerms(processedSearchTerms);
};
// ...
const visibleData = useMemo(() => {
// ...
}, [searchTerms]);
// ...
return (
<div>
// ...
<ImmediateParentOfTable
id={"Results"}
visibleData={visibleData} // User actions can affect the size of this
// ...
>
// ...
</div>
);
export default ListDatabaseResults;
Here's ImmediateParentOfTable:
import { Table, Pagination } from "#my-company/react";
// ...
return (
<Table
id={id}
pagination={{
render: (
dataSize,
{
pageCount,
pageOptions,
// ...
}
) => (
<Pagination
dataSize={dataSize}
pageCount={pageCount}
pageOptions={pageOptions}
gotoPage={gotoPage}
previousPage={previousPage}
nextPage={nextPage}
setPageSize={setPageSize}
canPreviousPage={canPreviousPage}
canNextPage={canNextPage}
pageIndex={pageIndex}
pageSize={pageSize}
pageSizeOptions={[10, 20, 50, 100]}
/>
),
manual: {
onPageChange: ({
pageIndex,
pageSize,
}: {
pageIndex: number;
pageSize: number;
}) => {
setPageIndex(pageIndex);
setPageSize(pageSize);
},
rowCount,
pageCount: tablePageCount,
},
isLoading: !!dataLoading,
}}
/>
);
The custom Table inside #my-company/react (already in use in other places, so, difficult to modify):
import {
CellProps,
Column,
Hooks,
Row,
SortingRule,
TableState,
useFlexLayout,
usePagination,
UsePaginationInstanceProps,
UsePaginationState,
useRowSelect,
useSortBy,
useTable,
} from 'react-table';
// ...
export interface TableProps<D extends Record<string, unknown>> {
id: string;
// ...
pagination?: Pagination<D>;
pageIndexOverride?: number; // This is the new prop I added that breaks pagination
}
const Table = <D extends Record<string, unknown>>({
id,
columns,
data,
// ...
pageIndexOverride,
}: TableProps<D>): JSX.Element => {
const {
state: { pageIndex, pageSize, sortBy },
// ...
} = useTable(
{
columns,
data,
autoResetPage,
initialState,
useControlledState: (state) => {
return React.useMemo(
() => ({
...state,
pageIndex: pageIndexOverride || state.pageIndex, // This always resets page index to the prop value, so changes from the pagination bar no longer work
}),
[state],
);
},
// ...
I've encountered a similar problem with react-table where most of my functionality (pagination, sorting, filtering) is done server-side and of course when a filter is changed I must set the pageIndex back to 0 to rectify the same problem you have mentioned.
Unfortunately, as you have discovered, controlled state in v7 of react-table is both poorly documented and apparently just completely non-functional.
I will note that the example code you linked from the docs
const [controlledPageIndex, setControlledPage] = React.useState(0)
useTable({
useControlledState: state => {
return React.useMemo(
() => ({
...state,
pageIndex: controlledPageIndex,
}),
[state, controlledPageIndex]
)
},
})
is actually invalid. controlledPageIndex cannot be used as a dep in that useMemo because it is in the outer scope and is accessed through closure. Mutating it will do nothing, which is actually noted by eslint react/exhaustive-deps rule so it's quite surprising that this made it into the docs as a way of accomplishing things. There are more reasons why it is unusable, but the point is that you can forget using useControlledState for anything.
My suggestion is to use the stateReducer table option and dispatch a custom action that will do what you need it to. The table reducer actions can have arbitrary payloads so you can do pretty much whatever you want. ajkl2533 in the github issues used this approach for row selection (https://github.com/TanStack/react-table/issues/3142#issuecomment-822482864)
const reducer = (newState, action) => {
if (action.type === 'deselectAllRows') {
return { ...newState, selectedRowIds: {} };
}
return newState;
}
...
const { dispatch, ... } = useTable({ stateReducer: reducer }, ...);
const handleDeselectAll = () => {
dispatch({ type: 'deselectAllRows' });
}
It will require getting access to the dispatch from the useTable hook though.

How Can I Setup `react-select` to work correctly with server-side data by using AsyncSelect?

I would like to setup a component react-select to work server-side data and do server-side filtering, but it doesn't work for a plethora of reasons.
Can you explain it and also show working code?
react-select has several examples in the documentation including an entire section dedicated to AsyncSelect which include inline code examples with codesandbox links.
It's worth noting that there are three unique props specific to the AsyncSelect
loadOptions
defaultOptions
cacheOptions
The primary difference between AsyncSelect and Select is that a Select is reliant on an options prop (an array of options) whereas the AsyncSelect is instead reliant on a loadOptions prop (an async function which provides a callback to set the options from an api).
Often api autocomplete lookups filter results on the server so the callback on the loadOptions does not make assumptions on filtering the results returned which is why they may need to be filtered client-side prior to passing them to the AsyncSelect state.
Here is a simple code example.
import React from 'react';
import AsyncSelect from 'react-select/async';
const filterOptions = (options, inputValue) => {
const candidate = inputValue.toLowerCase();
return options.filter(({ label }) => label.toLowerCase().includes(candidate);
};
const loadOptions = (inputValue, callback) => {
const url = `www.your-api.com/?inputValue=${inputValue}`;
fetch(url).then(resp => {
const toSelectOption = ({ id, name }) => ({ label: name, value: id });
// map server data to options
const asyncOptions = resp.results.map(toSelectOption);
// Filter options if needed
const filtered = filterOptions(asyncOptions, inputValue);
// Call callback with mapped and filtered options
callback(filtered);
})
};
const AsyncLookup = props => (
<AsyncSelect
cacheOptions
loadOptions={loadOptions}
defaultOptions
{...props}
/>
);
export default AsyncLookup
Let's start by me expressing the opinion that react-select seems great, but not very clearly documented. Personally I didn't fall in love with the documentation for the following reasons:
No search
All the props and put on a single page. If I do CTRL+F on something everything lights up. Pretty useless
Most descriptions are minimal and not describing the important edge cases, some are even missing
There are some examples, but not nearly enough to show the different varieties, so you have to do guesswork
And so I will try to help a bit with this article, by giving steps by steps, code and problems + solutions.
Step 1: Simplest form react-select:
const [options, setOptions] = useState([
{ id: 'b72a1060-a472-4355-87d4-4c82a257b8b8', name: 'illy' },
{ id: 'c166c9c8-a245-48f8-abf0-0fa8e8b934d2', name: 'Whiskas' },
{ id: 'cb612d76-a59e-4fba-8085-c9682ba2818c', name: 'KitKat' },
]);
<Select
defaultValue={options[0]}
isClearable
options={options}
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.id}
/>
It generally works, but you will notice that if I type the letter d which doesn't match any of the choices anywhere, choices stay, instead of showing "no options" as it should.
I will ignore this issue, since it is minor and seems unfixable.
So far so good, we can live with that small issue.
Step 2: Convert static data to server data
Our goal is now to simply swap the static data with server loaded data. Meh, how difficult could it be?
We will first need to swap <Select/> for <AsyncSelect/>. Now how do we load data?
So looking at the documentation there are multiple ways of loading data:
defaultOptions: The default set of options to show before the user starts searching. When set to true, the results for loadOptions('') will be autoloaded.
and
loadOptions: Function that returns a promise, which is the set of options to be used once the promise resolves.
Reading it carefully you understand defaultOptions needs to be a boolean value true and loadOptions should have a function returning the choices:
<AsyncSelect
defaultValue={options[0]}
isClearable
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.id}
defaultOptions
loadOptions={loadData}
/>
Looks great, we have remote data loaded. But we want to preset our default value now. We have to match it by Id, rather than choosing the first one. Here comes our first problem:
PROBLEM: You can't set the defaultValue in the very beginning, because you have no data to match it against. And if you try to set the defaultValue after component has loaded, then it doesn't work.
To solve that, we need to load data in advance, match the initial value we have, and once we have both of those, we can initialize the component. A bit ugly but that's the only way I could figure it out given the limitations:
const [data, setData] = useState(null);
const [initialObject, setInitialObject] = useState(null);
const getInitial = async () => {
// make your request, once you receive data:
// Set initial object
const init= res.data.find((item)=>item.id=ourInitialId);
setInitialObject(init);
// Set data so component initializes
setData(res.data);
};
useEffect(() => {
getInitial();
}, []);
return (
<>
{data!== null && initialObject !== null ? (
<AsyncSelect
isClearable
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.id}
defaultValue={initialObject}
defaultOptions={options}
// loadOptions={loadData} // we don't need this anymore
/>
) : null}
</>
)
Since we are loading the data ourselves, we don't need loadOptions so we will take it out. So far so good.
Step 3: Make filter with server-side filtering call
So now we need a callback that we can use for getting data. Let's look back at the documentation:
onChange: (no description, from section "StateManager Props")
onInputChange: Same behaviour as for Select
So we listen to documentation and go back to "Select Props" section to find:
onInputChange: Handle change events on the input`
Insightful...NOT.
We see a function types definition that seems to have some clues:
I figured, that string must by my text/query. And apparently it drops in the type of change. Off we go --
const [data, setData] = useState(null);
const [initialObject, setInitialObject] = useState(null);
const getInitial = async () => {
// make your request, once you receive data:
// Set initial object
const init= res.data.find((item)=>item.id=ourInitialId);
setInitialObject(init);
// Set data so component initializes
setData(res.data);
};
useEffect(() => {
getInitial();
}, []);
const loadData = async (query) => {
// fetch your data, using `query`
return res.data;
};
return (
<>
{data!== null && initialObject !== null ? (
<AsyncSelect
isClearable
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.id}
defaultValue={initialObject}
defaultOptions={options}
onInputChange={loadData} // +
/>
) : null}
</>
)
Data gets fetched with the right query, but options don't update as per our server data results. We can't update the defaultOptions since it is only used during initialization, so the only way to go would be to bring back loadOptions. But once we do, we have 2 calls on every keystroke. Blak. By countless hours and miracle of painstaking experimentation, we now figure out that:
USEFUL REVELATION: loadOptions actually fires on inputChange, so we don't actually need onInputChange.
<AsyncSelect
isClearable
getOptionLabel={(option) => option.name}
getOptionValue={(option) => option.id}
defaultValue={initialObject}
defaultOptions={options}
// onInputChange={loadData} // remove that
loadOptions={loadData} // add back that
/>
Things look good. Even our d search has automagically been fixed somehow:
Step 4: Update formik or whatever form value you have
To do that we need something that fires on select:
onChange: (no explanation or description)
Insightful...NOT. We have a pretty and colorful definition again to our rescue and we pick up some clues:
So we see the first param (which we don't know what it is can be object, array of array, null, or undefined. And then we have the types of actions. So with some guessing we figure out, it must be passing the selected object:
We will pass setFieldValue function as a prop to the component:
onChange={(selectedItem) => {
setFieldValue(fieldName, selectedItem?.id); // fieldName is also passed as a prop
}}
NOTE: careful, if you clear the select it will pass null for selectedItem and your JS will explode for looking for .id of undefined. Either use optional chaining or as in my case set it conditionally to '' (empty string so formik works).
Step 5: Final code:
And so we are all set with a fully functional reusable Autocomplete dropdown select server-fetching async filtering, clearable thingy.
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import AsyncSelect from 'react-select/async';
export default function AutocompleteComponent({
fieldName,
initialValue,
setFieldValue,
getOptionLabel,
queryField,
}) {
const [options, setOptions] = useState(null);
const [initialObject, setInitialObject] = useState(null);
// this function only finds the item from all the data that has the same id
// that comes from the parent component (my case - formik initial)
const findByValue = (fullData, specificValue) => {
return fullData.find((e) => e.id === specificValue);
};
const loadData = async (query) => {
// load your data using query HERE
return res.data;
};
const getInitial = async () => {
// load your data using query HERE
const fetchedData = res.data;
// match by id your initial value
const initialItem = findByValue(fetchedData, initialValue);
// Set both initialItem and data options so component is initialized
setInitialObject(initialItem);
setOptions(fetchedData);
}
};
// Hit this once in the beginning
useEffect(() => {
getInitial();
}, []);
return (
<>
{options !== null && initialObject !== null ? (
<AsyncSelect
isClearable
getOptionLabel={getOptionLabel}
getOptionValue={(option) => option.id}
defaultValue={initialObject}
defaultOptions={options}
loadOptions={loadData}
onChange={(selectedItem) => {
const val = (selectedItem === null?'':selectedItem?.id);
setFieldValue(fieldName, val)
}}
/>
) : null}
</>
);
}
AutocompleteComponent.propTypes = {
fieldName: PropTypes.string.isRequired,
initialValue: PropTypes.string,
setFieldValue: PropTypes.func.isRequired,
getOptionLabel: PropTypes.func.isRequired,
queryField: PropTypes.string.isRequired,
};
AutocompleteComponent.defaultProps = {
initialValue: '',
};
I hope this saves you some time.

Refactoring class component to functional component with hooks, getting Uncaught TypeError: func.apply is not a function

This is my first attempt to refactor code from a class component to a functional component using React hooks. The reason we're refactoring is that the component currently uses the soon-to-be-defunct componentWillReceiveProps lifecylcle method, and we haven't been able to make the other lifecycle methods work the way we want. For background, the original component had the aforementioned cWRP lifecycle method, a handleChange function, was using connect and mapStateToProps, and is linking to a repository of tableau dashboards via the tableau API. I am also breaking the component, which had four distinct features, into their own components. The code I'm having issues with is this:
const Parameter = (props) => {
let viz = useSelector(state => state.fetchDashboard);
const parameterSelect = useSelector(state => state.fetchParameter)
const parameterCurrent = useSelector(state => state.currentParameter)
const dispatch = useDispatch();
let parameterSelections = parameterCurrent;
useEffect(() => {
let keys1 = Object.keys(parameterCurrent);
if (
keys1.length > 0 //if parameters are available for a dashboard
) {
return ({
parameterSelections: parameterCurrent
});
}
}, [props.parameterCurrent])
const handleParameterChange = (event, valKey, index, key) => {
parameterCurrent[key] = event.target.value;
console.log(parameterCurrent[key]);
return (
prevState => ({
...prevState,
parameterSelections: parameterCurrent
}),
() => {
viz
.getWorkbook()
.changeParameterValueAsync(key, valKey)
.then(function () {
Swal.fire({
position: "center",
icon: "success",
title:
JSON.stringify(key) + " set to " + JSON.stringify(valKey),
font: "1em",
showConfirmButton: false,
timer: 2500,
heightAuto: false,
height: "20px"
});
})
.otherwise(function (err) {
alert(
Swal.fire({
position: "top-end",
icon: "error",
title: err,
showConfirmButton: false,
timer: 1500,
width: "16rem",
height: "5rem"
})
);
});
}
);
};
const classes = useStyles();
return (
<div>
{Object.keys(parameterSelect).map((key, index) => {
return (
<div>
<FormControl component="fieldset">
<FormLabel className={classes.label} component="legend">
{key}
</FormLabel>
{parameterSelect[key].map((valKey, valIndex) => {
console.log(parameterSelections[key])
return (
<RadioGroup
aria-label="parameter"
name="parameter"
value={parameterSelections[key]}
onChange={(e) => dispatch(
handleParameterChange(e, valKey, index, key)
)}
>
<FormControlLabel
className={classes.formControlparams}
value={valKey}
control={
<Radio
icon={
<RadioButtonUncheckedIcon fontSize="small" />
}
className={clsx(
classes.icon,
classes.checkedIcon
)}
/>
}
label={valKey}
/>
</RadioGroup>
);
})}
</FormControl>
<Divider className={classes.divider} />
</div>
);
})
}
</div >
)};
export default Parameter;
The classes const is defined separately, and all imports of reducers, etc. have been completed. parameterSelect in the code points to all available parameters, while parameterCurrent points to the default parameters chosen in the dashboard (i.e. what the viz initially loads with).
Two things are happening: 1. Everything loads fine on initial vizualization, and when I click on the Radio Button to change the parameter, I can see it update on the dashboard - however, it's not actually showing the radio button as being selected (it still shows whichever parameter the viz initialized with as being selected). 2. When I click outside of the Filterbar (where this component is imported to), I get Uncaught TypeError: func.apply is not a function. I refactored another component and didn't have this issue, and I can't seem to determine if I coded incorrectly in the useEffect hook, the handleParameterChange function, or somewhere in the return statement. Any help is greatly appreciated by this newbie!!!
This is a lot of code to take in without seeing the original class or having a code sandbox to load up. My initial thought is it might be your useEffect
In your refactored code, you tell your useEffect to only re-run when the props.parameterCurrent changes. However inside the useEffect you don't make use of props.parameterCurrent, you instead make use of parameterCurrent from the local lexical scope. General rule of thumb, any values used in the calculations inside a useEffect should be in the list of re-run dependencies.
useEffect(() => {
let keys1 = Object.keys(parameterCurrent);
if (
keys1.length > 0 //if parameters are available for a dashboard
) {
return ({
parameterSelections: parameterCurrent
});
}
}, [parameterCurrent])
However, this useEffect doesn't seem to do anything, so while its dependency list is incorrect, I don't think it'll solve the problem you are describing.
I would look at your dispatch and selector. Double check that the redux store is being updated as expected, and that the new value is making it from the change callback, to the store, and back down without being lost due to improper nesting, bad key names, etc...
I'd recommend posting a CodeSandbox.io link or the original class for further help debugging.

How can I use Search with an API endpoint as my source? Is this possible with semantic-ui-react?

I would like to use an API endpoint to pull search results in react-semantic-ui. So far the examples given work with local source. The one that seems to implement an API is via Semantic-UI using jquery. Semantic-UI-React does not seem to have examples where results can come from an API.
so far, I have my handleSearchChange fetching data from the API into state. I then pass the response data to my results:
handleSearchChange = (e, { value }) => {
const { fetchAPIData, response } = this.props;
fetchAPIData(value);
this.setState({ isLoading: true, value, results: response });
setTimeout(
() =>
this.setState({
isLoading: false
}),
300
);
};
I then call resultRenderer passing my source which is rendering the results via a Grid and/or even a List.
return (
<Search
fluid
placeholder="Search"
style={searchWidth}
loading={isLoading}
minCharacters={2}
showNoResults={false}
selectFirstResult={false}
resultRenderer={source}
onResultSelect={this.handleResultSelect}
onSearchChange={this.handleSearchChange}
results={results}
value={value}
/>
);
This seems to work and load results when a search occurs. However, I reckon since this is merely a hack, I am getting this console error:
index.js:2178 Warning: Failed prop type: The prop `title` is marked as
required in `SearchResult`, but its value is `undefined`.
I understand the error well, but I do not want to use my source with title, description, price etc since my result is coming from an API.
Another error is:
Warning: Each child in an array or iterator should have a unique "key"
prop.
I have tried adding the key as:
const source = ({ id, username }) => (
<Grid key={id} content={username}
......
......
......
);
and or:
const source = ({ id, username }) => (
<List key={id} content={username} />
);
But this does not solve it.
My question thus is, is it possible to use an API with the Search in Semantic-UI-React and if so, how can it efficiently be implemented?
Thanks

Resources