I have a container ponent in my React project that houses two separate ponents. One ponent is a list of locations and the other is a filtering section for that list.
The filter section dispatches an action up to the container and the container re orders the list based on the criteria and passes a final "filtered" list back to the locations list ponent.
Right now the Sort By filter is a select dropdown with option values set to strings (as shown below), that are then passed up to the container.
<SelectDropdown value={sort} onChange={handleSortChange}>
<option value={''}>Select</option>
<option value={'alphaAsc'}>Alphabetical Asc</option>
<option value={'alphaDesc'}>Alphabetical Desc</option>
</SelectDropdown>
Inside the container I have a simple alphabetical sortBy function to sort and render the list in ascending or descending order based on the address value, and that's where my app keeps crashing and throwing the error TypeError: Cannot read property 'localeCompare' of undefined
but I'm not entirely sure why.
My original function is below along with the line where I'm using it.
Alphabetical Sort function
export const alphabeticalSort = property => {
let sortOrder = 1;
if (property[0] === '-') {
sortOrder = -1;
property = property.substr(1);
}
return function(a, b) {
if (sortOrder === -1) {
return b[property].localeCompare(a[property]);
} else {
return a[property].localeCompare(b[property]);
}
};
};
How I'm calling it
if (sort === 'alphaAsc') {
filteredLocations = filteredLocations.sort(alphabeticalSort(l => l.address.addressLine1)).slice();
}
Filtered Locations
const allLocations = store.get('locations');
let filteredLocations = allLocations.slice();
Location Structure
locations: [
{
name: 'Fictional Place',
address: {
addressLine1: '123 Imaginary Drive',
line2: '',
city: 'Philadelphia',
state: 'PA'
zip: '12345'
}
...
},
{
name: 'California Dreaming',
address: {
addressLine1: '456 Somewhere Blvd',
line2: '',
city: 'Sacramento',
state: 'CA'
zip: '67890'
}
...
},
....
I have a container ponent in my React project that houses two separate ponents. One ponent is a list of locations and the other is a filtering section for that list.
The filter section dispatches an action up to the container and the container re orders the list based on the criteria and passes a final "filtered" list back to the locations list ponent.
Right now the Sort By filter is a select dropdown with option values set to strings (as shown below), that are then passed up to the container.
<SelectDropdown value={sort} onChange={handleSortChange}>
<option value={''}>Select</option>
<option value={'alphaAsc'}>Alphabetical Asc</option>
<option value={'alphaDesc'}>Alphabetical Desc</option>
</SelectDropdown>
Inside the container I have a simple alphabetical sortBy function to sort and render the list in ascending or descending order based on the address value, and that's where my app keeps crashing and throwing the error TypeError: Cannot read property 'localeCompare' of undefined
but I'm not entirely sure why.
My original function is below along with the line where I'm using it.
Alphabetical Sort function
export const alphabeticalSort = property => {
let sortOrder = 1;
if (property[0] === '-') {
sortOrder = -1;
property = property.substr(1);
}
return function(a, b) {
if (sortOrder === -1) {
return b[property].localeCompare(a[property]);
} else {
return a[property].localeCompare(b[property]);
}
};
};
How I'm calling it
if (sort === 'alphaAsc') {
filteredLocations = filteredLocations.sort(alphabeticalSort(l => l.address.addressLine1)).slice();
}
Filtered Locations
const allLocations = store.get('locations');
let filteredLocations = allLocations.slice();
Location Structure
locations: [
{
name: 'Fictional Place',
address: {
addressLine1: '123 Imaginary Drive',
line2: '',
city: 'Philadelphia',
state: 'PA'
zip: '12345'
}
...
},
{
name: 'California Dreaming',
address: {
addressLine1: '456 Somewhere Blvd',
line2: '',
city: 'Sacramento',
state: 'CA'
zip: '67890'
}
...
},
....
Share
Improve this question
edited Apr 16, 2020 at 18:50
Josh
asked Apr 16, 2020 at 17:50
JoshJosh
1,2355 gold badges27 silver badges52 bronze badges
9
-
1
Add
filteredLocations
to your question – Anurag Srivastava Commented Apr 16, 2020 at 18:05 - Just added the filteredLocations and what the location structure looks like – Josh Commented Apr 16, 2020 at 18:44
- Were you able to get help from the below answer? – Anurag Srivastava Commented Apr 17, 2020 at 15:05
-
Hey unfortunately not, It's throwing a new error now saying
TypeError: Cannot read property '0' of undefined
– Josh Commented Apr 17, 2020 at 17:07 - 1 Got it, thank you! – Josh Commented Apr 21, 2020 at 14:55
1 Answer
Reset to default 1You could have something like below, you enter the property as a string with "."
let locations = [{
name: 'Fictional Place',
address: {
addressLine1: '123 Imaginary Drive',
line2: '',
city: 'Philadelphia',
state: 'PA',
zip: '12345'
}
},
{
name: 'California Dreaming',
address: {
addressLine1: '456 Somewhere Blvd',
line2: '',
city: 'Sacramento',
state: 'CA',
zip: '67890'
}
}
]
const alphabeticalSort = property => {
let sortOrder = 1 // Add your logic for asc/desc here
, propArr = property.split(".")
return function(a, b) {
if (sortOrder === -1) {
return b[propArr[0]][propArr[1]].localeCompare(a[propArr[0]][propArr[1]]);
} else {
return a[propArr[0]][propArr[1]].localeCompare(b[propArr[0]][propArr[1]]);
}
};
};
console.log(locations.sort(alphabeticalSort("address.addressLine1")))
console.log(locations.sort(alphabeticalSort("address.state")))