On immutability and sanity

crazy homer simpson

Introduction

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 (
            
                {transaction.amount}
                {transaction.date}
                {transaction.client}
            
    })
}

// 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.

2 Comments, RSS

  1. baju zumba October 29, 2017 @ 1:45 pm

    I’m really enjoying the design and layout of
    your blog. It’s a very easy on the eyes which makes it much more pleasant for me to come here and visit more often. Did you hire out a
    developer to create your theme? Excellent work!

  2. Natalie Chvilicek May 25, 2018 @ 9:04 pm

    I really can’t believe how great this site is. Keep up the good work. I’m going to tell all my friends about this place.

Your email address will not be published. Required fields are marked *

*