1

I have a basic ES6 react app and am trying to use momentJS to manipulate some dates. For some reason I keep getting month.add is not a function

Currently the code I have is this:

export default class CalendarApp extends React.Component {

constructor() {
    super();

    this.state = {
        currentDate: Moment().format(),
        month: Moment().format('MMMM'),
        year: Moment().format('YYYY')
    }

    // Bind Methods to this
    this.previousMonth = this.previousMonth.bind(this);
    this.nextMonth = this.nextMonth.bind(this);
}

previousMonth() {
    let month = this.state.month;
    month.add(-1, 'months');
    this.setState({
        month: month
    })
}

nextMonth() {
    let month = this.state.month;
    month.add(1, 'months');
    this.setState({
        month: month
    })
}

render() {
    return (
        <div className="calendar">
            <div className="calendar-container" style={ hideCalendar }>
                <caption>
                    <button className="previous-month" onClick={ this.previousMonth }>Prev</button>
                    <button className="next-month" onClick={ this.nextMonth }>Next</button> 
                    <div className="calendar-month">
                        <span>{ this.state.month } { this.state.year }</span>
                    </div>
                </caption>
            </div>
        </div>
    )
}

}

I have tried various versions of setting the initial state using Moment().month() etc but nothing seems to work. Any help would be much appreciated.

2 Answers 2

4

When you do .format() you are turning it into a string, it's no longer a momentJS object.

moment().add(1, 'months') // A moment object

moment().add(1, 'months').subtract(6, 'days') // Can still manipulate

moment().add(1, 'months').subtract(6, 'days').format() // A final string, can't call moment funcs on it

Also there's no need to create multiple objects if they're all using the same time -

const momentNow = Moment();

this.state = {
  currentDate: momentNow.format(),
  month: momentNow.format('MMMM'),
  year: momentNow.format('YYYY')
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply. If I am only creating 1 object in state, for example currentDate, would it be possible to then later use this.state.currentDate.format("MMMM")?
Yep you can, although the current time is probably taken at the point of creating the object rather than when you do a .format on it - probably not an issue but worth bearing in mind
3

Your state.month is a string. That's causing the issue.

Try this

constructor() {
    super();

    this.state = {
        currentDate: Moment(),
        month: Moment().format('MMMM'),
        year: Moment().format('YYYY')
    }

    // Bind Methods to this
    this.previousMonth = this.previousMonth.bind(this);
    this.nextMonth = this.nextMonth.bind(this);
}

previousMonth() {
    let date = this.state.currentDate;
    date.add(-1, 'months');
    this.setState({
        currentDate: date,
        month: date.format('MMMM'),
        year: date.format('YYYY')
    });
}

nextMonth() {
    let date = this.state.currentDate;
    date.add(1, 'months');
    this.setState({
        currentDate: date,
        month: date.format('MMMM'),
        year: date.format('YYYY')
    });
}

Comments

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.