Closed TreeMama closed 1 year ago
note: inspecting data flow between MapScreen.tsx and InfoScreen.tsx
It looks like the following function in MapScreen.tsx is cause to this bug:
function extractTreeNameQuery(item) {
const treename = item.item.speciesNameCommon
console.log(
'Extracted Tree Common Name: ' +
treename +
' from tooltip. Passing to InfoScreen to show more tree info',
)
return treename
}
I think we should try
const treename = item.item.speciesNameScientific ?
item.item.speciesNameScientific :
item.item.speciesNameCommon;
This will conditionally pass the scientific name of it exists, and if not, only then passes the common name into the query, which is then passed to the infoScreen as a handler.
however, within the InfoScreen.tsx, the following hook only filters through the COMMON names:
useEffect(() => {
const { params } = props.route
if (params && params.treeNameQuery !== undefined) {
const completeList = speciesDataList
const query = params.treeNameQuery?.toUpperCase()
const filteredList = completeList.filter(
(tree) => tree.COMMON.toUpperCase().indexOf(query) > -1,
)
setSelectedTree(filteredList.length == 0 ? undefined : filteredList[0])
setIsFromMapScreen(true)
}
}, [props.route])
I created a new branch that filters via SCIENTIFIC name instead of COMMON.
This should resolve the issues with Maples, Oak, or any other trees that have overlapping COMMON names.
But, maybe the query passed should be an object, i.e. {treeName: 'White Oak', scientific: 'false'} that the infoScreen could then resolve whether or not the name being passed is scientific or not.
https://github.com/TreeMama/iSeaTree-React-Prototype/compare/develop...issue/455
ok, so I added the following to the InfoScreen.tsx
let query = params.treeNameQuery?.toUpperCase().toString();
console.log(`query: ${query}`);
// const filteredList = completeList.filter(
// (tree) => tree.COMMON.toUpperCase().indexOf(query) > -1,
// )
// Replace double-quotes with single-quotes to match pattern in datastore
if (query.includes('"')) {
query.replace(/"/g, "'");
}
// Create a Regular Expression based on the query
const reg = new RegExp(`^${query}$`)
console.log(reg);
// Filter tree list by scientific name using search(regex) to find a match
const scientificList = completeList.filter(
(tree) => tree.SCIENTIFIC.toUpperCase().search(reg) > -1,
)
The following creates a strict regular expression that matches the scientific name. Before it was matching any substring, ie Sugar Maple would match Sugar Maple 'Bonfire'.
const reg = new RegExp(`^${query}$`);
Would still have to test on Oaks.
Solution: The code was updated to filter the tree list by Scientific Names instead of Common Names. The updated code normalizes the query string by replacing any double-quotes with single-quotes to match the pattern in the data store, i.e. will match Sugar Maple "Bonfire" to Sugar Maple 'Bonfire', creates a regular expression based on the normalized query, and then filters the tree list by scientific name using the search method.
If no matches are found, the query is trimmed, for other cases like Acer campestre 'Evelyn' and filtered again (it's possible the speciesList.json still needs populating).
If there are still no matches, the tree list is finally filtered by common name. The selected tree is then set to the first item in the filtered list, or undefined if the list is empty.
useEffect(() => {
const { params } = props.route
if (!params || params.treeNameQuery === undefined) {
return;
}
const completeList = speciesDataList;
const query = params.treeNameQuery?.toUpperCase().toString();
// Replace double-quotes with single-quotes to match pattern in datastore
const normalizedQuery = query.replace(/"/g, "'");
// Create a Regular Expression based on the query
let reg = new RegExp(`^${normalizedQuery}$`);
console.log(reg);
// Filter tree list by scientific name using search(regex) to find a match
const filterByScientific= (list, regex) =>
list.filter((tree) => tree.SCIENTIFIC.toUpperCase().search(regex) > -1);
let filteredList = filterByScientific(completeList, reg)
if (filteredList.length === 0){
console.log('No matches found in scientific list, first trimming query')
let trim = query.match(/'.*'/g) || query.match(/‘.*?’/g, '');
let trimmedQuery = query.replace(` ${trim}`, '');
console.log(`trimmedQuery: ${trimmedQuery}, trim: ${trim}`);
filteredList = filterByScientific(completeList, new RegExp(`^${trimmedQuery}$`));
}
if (filteredList.length === 0) {
console.log("Still no matches found in scientific list, checking common name")
filteredList = completeList.filter(
(tree) => tree.COMMON.toUpperCase().search(reg) > -1
);
}
setSelectedTree(filteredList.length == 0 ? undefined : filteredList[0])
setIsFromMapScreen(true)
}, [props.route, speciesDataList]);
ToDO:
This is regarding record '4KO8t1YyE0tKpsd4PPTX' in prod (entered Oct 18 2022).
The species info is: speciesNameCommon : "Sugar Maple" speciesNameScientific : "Acer saccharum"
However, it keeps showing "Acer saccharum 'Bonfire'" when user clicks 'More Tree Info'. I'm also seeing the same problem with 'White oak' (which for the photo location in Nashville being shown below is pulling up the data for 'Oregon Oak (aka White Oak or Garry Oak').
Investigate why - and fix.
White Oak / Oregon Oak location:
Video repo of the 'Acer saccharum' issue: https://user-images.githubusercontent.com/62637055/221598060-eb17f5e0-0be7-4d42-bb22-002347e32062.mov