0

My data sort method for some reason is not working in my react app i.e return value is not changing

Consider this as my state and variables

    state = {
        percentageHighestOrLeast: "highest", //highest or lowest
        townOrCounty: "town",  //town or county
        amountMaximumOrMinimum: "maximum" //maximum or minimum
    }

Now In render I am checking if data is loaded without any error and then calling a function

if (!this.props.mainListFetching && !this.props.mainListError) {  
            this.highestOrLeast = this.sortingData(this.props.mainList, this.state.percentageHighestOrLeast)
            this.townOrCounty = this.sortingData(this.props.mainList, this.state.townOrCounty)
            this.amountMaximumOrMinimum = this.sortingData(this.props.mainList, this.state.amountMaximumOrMinimum)
        }

My this.sortinfData looks like this (this method is successfully being called)

sortingData = (data, type) => {
   data.sort((a, b) => {
       if (type == "highest") return (a["percentage.funded"] - b["percentage.funded"])
       if (type == "lowest") return (b["percentage.funded"] - a["percentage.funded"])
       if (type == "town") return (a["type"].localeCompare(b["type"]))
       if (type == "county") return (b["type"].localeCompare(a["type"]))
       if (type == "maximum") return (a["amt.pledged"] - b["amt.pledged"])
       if (type == "minimum") return (b["amt.pledged"] - a["amt.pledged"])
    })
 return data
}

If i console.log this.highestOrLeast or 'this.amountMaximumOrMinimum' or this.townOrCounty, they all throw same result

This is how my data looks

[
  {
    "s.no": 0,
    "amt.pledged": 15823,
    "blurb": "'Catalysts, Explorers & Secret Keepers: Women of Science Fiction' is a take-home exhibit & anthology by the Museum of Science Fiction.",
    "by": "Museum of Science Fiction",
    "country": "US",
    "currency": "usd",
    "end.time": "2016-11-01T23:59:00-04:00",
    "location": "Washington, DC",
    "percentage.funded": 186,
    "num.backers": "219382",
    "state": "DC",
    "title": "Catalysts, Explorers & Secret Keepers: Women of SF",
    "type": "Town",
    "url": "/projects/1608905146/catalysts-explorers-and-secret-keepers-women-of-sf?ref=discovery"
  },
  {
    "s.no": 1,
    "amt.pledged": 6859,
    "blurb": "A unique handmade picture book for kids & art lovers about a nervous monster who finds his courage with the help of a brave little girl",
    "by": "Tyrone Wells & Broken Eagle, LLC",
    "country": "US",
    "currency": "usd",
    "end.time": "2016-11-25T01:13:33-05:00",
    "location": "Portland, OR",
    "percentage.funded": 8,
    "num.backers": "154926",
    "state": "OR",
    "title": "The Whatamagump (a hand-crafted story picture book)",
    "type": "Town",
    "url"

[Question:] Can anyone help me figure out what I might be doing wrong here?

10
  • 1
    An object can't have a property with dot in it that isn't quoted like amt.pledged. What does the data really look like? Commented Nov 11, 2018 at 1:23
  • @charlietfl snippet of data is in the question Commented Nov 11, 2018 at 1:24
  • 1
    But that is simply not valid is my point Commented Nov 11, 2018 at 1:25
  • @CertainPerformance You mean something like this? (a.percentage.funded - b.percentage.funded) This is throwing an error saying Cannot read property 'funded' of undefined Commented Nov 11, 2018 at 1:25
  • Provide sample of the actual valid data not something you copied from browser console. Having a runnable minimal reproducible example would prevent guessing Commented Nov 11, 2018 at 1:30

2 Answers 2

1

I would post a comment if I could, but I do not have the reputation. Anyway, keep in mind that if you provided a full example of what was happening it would be easier to help. There are a lot of issues with the information you provided that make it difficult to help.

The updated data you provided still seems incomplete. The view I have is cut off in the second item of the array after the property:

"state": "OR",

You reference sorting by town or county (state.townOrCounty), but the data just seems to have state and country.

Again, with something like this, it might help to make a jsfiddle or something to show what works and what does. I tried creating one at https://jsfiddle.net/c5fgy291/4/. You are welcome to look at it and see if it helps. it sorts your limited data from min to max or max to min. I gave up on calling the sort function the way you did, but that might still work. Sorry I couldn't be more help.

A couple of notes I had right off the bat is that it looked like you were trying to change the state of your object by directly editing its value; ie

if (!this.props.mainListFetching && !this.props.mainListError) {  
    this.highestOrLeast = this.sortingData(this.props.mainList, this.state.percentageHighestOrLeast)
    this.townOrCounty = this.sortingData(this.props.mainList, this.state.townOrCounty)
    this.amountMaximumOrMinimum = this.sortingData(this.props.mainList, this.state.amountMaximumOrMinimum)
}

You should be using the setState function. In the fiddle I made, I wrote a separate function that showed it being used. In my fiddle, I assumed you wanted to change the order that the items in the data were displayed based on amount pledged, or town they live in, or something. To do that, your data should be part of the state of the component. That way, you can sort your data (ideally, a copy of the data, I think), and then update the state. I added buttons in the fiddle that let you sort by min and max.

So, here is my initial state declaration.

 state = {
        percentageHighestOrLeast: "highest", 
        townOrCounty: "town",  
        amountMaximumOrMinimum: "minimum", 
        pledges: data.slice(0),   //  data is outside of component In my implementation
    }

And here, this is a block that you could place somewhere when you want to make sure it is sorted. Not in the render function, though, because that is called after the state is updated. In my example, it is called from a button click. {

  if (!this.props.mainListFetching && !this.props.mainListError) {
    const newData = this.sortingData(this.state.pledges, "somethingHere");
    this.setState({
        pledges: newData,
    })                

}

When the setState is called, the render function will automatically be called. My render function is something like this (I'm showing this to illustrate that the having the data included in the state lets it update automatically. also note that I wrote a separate Pledge component).

render() {
    <h3>Pledges</h3>

      {this.state.pledges.map((pledge, i) => <Pledge { ...pledge } key={pledge['s.no']}  />)}
    </div>;
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for answer. this.highestOrLeast = [] this.townOrCounty = [] this.amountMaximumOrMinimum = [] are inside constructor. I am not trying to change state anywhere in my code. I am updating the data snippet
0

Your function is returning the same data that you passed through the first param, you're not attributing the sort method to the value which will be returned.

sortingData = (data, type) => {
       data.sort((a, b) => {
           if (type == "highest") return (a["percentage.funded"] - b["percentage.funded"])
           if (type == "lowest") return (b["percentage.funded"] - a["percentage.funded"])
           if (type == "town") return (a["type"].localeCompare(b["type"]))
           if (type == "county") return (b["type"].localeCompare(a["type"]))
           if (type == "maximum") return (a["amt.pledged"] - b["amt.pledged"])
           if (type == "minimum") return (b["amt.pledged"] - a["amt.pledged"])
        })
     return data
    }

What you need to do is simply change:

sortingData = (data, type) => {
           return data.sort((a, b) => {
               if (type == "highest") return (a["percentage.funded"] - b["percentage.funded"])
               if (type == "lowest") return (b["percentage.funded"] - a["percentage.funded"])
               if (type == "town") return (a["type"].localeCompare(b["type"]))
               if (type == "county") return (b["type"].localeCompare(a["type"]))
               if (type == "maximum") return (a["amt.pledged"] - b["amt.pledged"])
               if (type == "minimum") return (b["amt.pledged"] - a["amt.pledged"])
            })
        }

Or even just data = data.sort then return data

1 Comment

Lol, nice debugging skills. I spent a couple minutes looking at it without noticing anything.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.