1

In my react app, I'm receiving a cost (like 990.00) from the API as a string. I'm storing it in a material UI table with sorting function. To sort the cost, it should be in number format. I'm using toFloat() to convert it to a number but I get 900 only. If I modify it to toFloat().toFixed(2), it will be convert again into a string. If I modify it to toFloat().round(2), no output at all.

var cost = '900.00'
var numericCost = toFloat(cost) //type - number but no decimal zeros
var numericCost = toFloat(cost).toFixed(2) //type - string, so can't sort it
var numericCost = toFloat(cost).round(2) //no output (can't see the data)

How do I get that number with type - number with following decimal zeros ?

Here is the Sorting method:

let counter = 0;
function createData(projectId, projectName, projectStatus, totalCost, paymentStatus, clientName, email, phone) {
    counter += 1;
    return { id: counter, projectId, projectName, projectStatus, totalCost, paymentStatus, clientName, email, phone };
}

function desc(a, b, orderBy) {
    if (b[orderBy] < a[orderBy]) {
        return -1;
    }
    if (b[orderBy] > a[orderBy]) {
        return 1;
    }
    return 0;
}

function getSorting(order, orderBy) {
    return order === 'desc' ? (a, b) => desc(a, b, orderBy) : (a, b) => -desc(a, b, orderBy);
}

class AllTable extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            order: 'asc',
            orderBy: 'userName',
            data: [],
        };
    }

componentDidMount() {
        API.get('url')
            .then(({ data }) => {
                this.setState({
                    data: data.response.map(
                        job => (
                            createData(
                                job.project_id,
                                parseFloat(job.total),
                                job.payment_status,
                            )
                        )
                    )
                })
            })
            .catch((err) => {
                console.log("AXIOS ERROR: ", err);
            })
    }

handleRequestSort = (event, property) => {
        const orderBy = property;
        let order = 'desc';
        if (this.state.orderBy === property && this.state.order === 'desc') {
            order = 'asc';
        }
        this.setState({ order, orderBy });
    };

    render(){
      return(
          {data
            .sort(getSorting(order, orderBy))
               .map(n => {
                  return (
                    <TableRow
                        hover
                        tabIndex={-1}
                        key={n.id}
                    >
                       <TableCell className={classes.tdWidth}><div className={classes.cellWidth}>${n.totalCost}</div></TableCell>
                       <TableCell className={classes.tdWidth}><div className={classes.cellWidth}>{n.paymentStatus}</div></TableCell>
                    </TableRow>
           })}
      )
}

}
10
  • 4
    You don't; a number cannot store following zeros. This is most likely an XY problem, please tell us what your goal is. Commented May 16, 2019 at 8:00
  • 1
    please add the sorting part. btw, where is toFloat from? Commented May 16, 2019 at 8:02
  • 1
    but I get 900 only thats what you have. Commented May 16, 2019 at 8:02
  • 1
    I don't see the issue tbh; 1. api response 2. parse to float 3. sort 4. output as toFixed(2) Commented May 16, 2019 at 8:03
  • 3
    Possible duplicate of javascript number precision without converting to String and How can I round a number in JavaScript? .toFixed() returns a string? Commented May 16, 2019 at 8:03

3 Answers 3

1

The core issue you're trying to solve is sorting by some version of the number (a numeric value), and then displaying another (a string, with defined precision). The solution is to separate out those two concerns, such that you're not using the same value to both sort and display:

render() {
  let data = this.props.data.sort((a, b) => {
    // This is the sorting function, so we need to treat the values as a number
    return toFloat(a.cost) - toFloat(b.cost);
  });

  return data.map(n => {
    // Now we're showing the data, so treat it as a string
    // It's already a string fetched from the API in the format needed, so just use directly
    return (
      <TableRow key={n.id}>
        <TableCell>{n.cost}</TableCell>
      </TableRow>
    );
  });
}
Sign up to request clarification or add additional context in comments.

Comments

0

So i will reformule my Answer, toFixed always returns a string number because in javascript decimals can't be represented in binary floating-point systems with full accuracy, for example 10.2 is in fact 10.2........ (many numbers after decimal point)

so to fixed cuts a part of the number as a string in order to give us the result that we want with precision.

in order to fix this you need to create your own function, and here's a link to help you: https://exoboy.wordpress.com/2011/07/14/the-problems-with-tofixed-in-javascript/

you will need the following code: (i'm not the owner of the code i got it from the link that i mentionned)

Number.prototype.trimNum = function(places,rounding){

(rounding != 'floor' && rounding != 'ceil') ? rounding = 'round' : rounding = rounding;

var result, num = this, multiplier = Math.pow( 10,places );

result = Math[rounding](num * multiplier) / multiplier;

return Number( result );

}

so to call this function you just have to use num.trimNum( places, rounding ); where places are number of places after decimal point, and rounding is a string value ('round'/'ceil'/'floor')

This will solve your problem in most of the cases, but in your case '999.00' it will still show 999,but it won't affect the result because 999 and 999.00 will have the same result

2 Comments

Please read the question: "If I modify it to toFloat().toFixed(2), it will be convert again into a string"
i have edited the answer,i hope it will help you, good luck.
-1

Try this:

var cost = '900.00'
var numericCost = parseFloat(cost).toFixed(2)

1 Comment

Please read the question: "If I modify it to toFloat().toFixed(2), it will be convert again into a string"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.