On immutability and sanity

November 07, 2017 0 Comments

On immutability and sanity

 

 


This is just a little article to share a problem I encountered. I was tasked with building a CRM and transactions had to be filtered by date. Nothing fancy about all this. You check if the transaction's date is between two other dates the user gives you ( a start date and an end one ).

The code

Well, here is how the code looked before I managed to solve it. I was using React with this code. I used the popular javascript library moment.js to work with dates.

renderTransactions(){ return this.props.transactions.filter( transaction => { const start = moment(this.state.startDate) const end = moment(this.state.endDate) const tDate = moment(transaction.date) return tDate.isBetween(start, end) // Compare dates here }) .map( ( transaction, i ) => { transaction.date = moment(transaction.date).format('DD/MM/YYYY') return ( <tr key={i}> <td>{transaction.amount}</td> <td>{transaction.date}</td> <td>{transaction.client}</td> </tr> })
} // etc.. etc...

Ok, can you see where the problem is? The first time the component renders, everything is fine, the dates are properly filtered. But, as soon as I modify the dates, nothing works anymore...

The problem was here:

transaction.date = moment(transaction.date).format('DD/MM/YYYY')

See how stupid that is? I mutate the state of my array with this line. On the next render, the date field is not longer a Date object that the moment library can work with, but a String...

Solving it, and restoring my sanity...

Take one:

Don't use this.props directly. If I used a reference to this.props.transactions in my function, the problem wouldn't have happened. Every time the function would run, a fresh copy of this.props.transactions would be used. Even if I kept the problematic line with the direct mutation, it would work.

Take two:

Immutability. Don't mutate the state of your application directly. This line would have solved everything:

const date = moment(transaction.date).format('DD/MM/YYYY')

Done... Problem solved.

Conclusion

I'm just writing this to make sure I don't make the same stupid mistake again. I spent way to much time on this... I'm tired and I hate programming.



Tag cloud