最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Getting TypeError: Cannot read property 'localeCompare' of undefined for my sortBy function in my R

programmeradmin4浏览0评论

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
 |  Show 4 more ments

1 Answer 1

Reset to default 1

You 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")))

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论