Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Drew Butcher
Drew Butcher
33,160 Points

Setting video.currentTime in componentDidMount with Reactjs (HTML5 Video Element) not working in Safari?

I am using reactjs with the flux architecture to run a html5 video. I store the users currentTime in my database so when they come back to the page the user has the option to resume or restart the video. I was setting the videos's currentTime with this.video.currentTime in componentDidMount. This seems to work beautifully except in Safari!!!! Am I doing something wrong? the video is give a refs in accordance to the following instructions https://facebook.github.io/react/docs/more-about-refs.html

Here is where I reference my video in componentDidMount:

componentDidMount: function(){
    if (this.video !== null) {
        this.video.currentTime = this.props.persistedCurrentTime;
        this.video.addEventListener('ended', this.handleOnEnded);
    }
},

In the render I do a refs on the video which is why i'm using this.video above. Here is the render of this component:

render: function() {
    return (
        <video
            ref={function(ref) { this.video = ref }.bind(this)}
            controls={false}
            onClick={this.handleClick}
            onPlay={this.handleOnPlay}
            onPause={this.handleOnPause}
            onTimeUpdate={this.handleTimeUpdate}
            onVolumeChange={this.handleVolumeChange}
            onMute={this.handleMute}
            id="video">
            <source src={this.props.src} type="video/mp4" />
        </video>
    );
}

To try and better understand what was happening I used several console.log statements in the componentDidMount. Here is what I printed:

 if (this.video !== null) {
        console.log("this.video = "+this.video)
        console.log("this.props.persistedCurrentTime = "+this.props.persistedCurrentTime)
        console.log("this.video.currentTime = "+this.video.currentTime)
        this.video.currentTime = this.props.persistedCurrentTime;
        console.log("this.video.currentTime = "+this.video.currentTime)
}

In the console of Chrome I receive the following feedback:

 this.video = [object HTMLVideoElement]
 this.props.persistedCurrentTime = 35
 this.video.currentTime = 0
 this.video.currentTime = 35

Which is what I expected to receive, as it progresses the video's currentTime to 35 seconds.

However, in Safari I receive the following:

[Log] this.video = [object HTMLVideoElement] (main.js, line 770)
[Log] this.props.persistedCurrentTime = 35 (main.js, line 771)
[Log] this.video.currentTime = 0 (main.js, line 772)
[Log] this.video.currentTime = 0 (main.js, line 774)

notice that in the last line the video.currentTime is not 35 seconds :( WHY!!!!!! It is clear that the video element has mounted from the first line. What's even more crazy is that if I do this.video.currentTime = 35 in the console, the video moves to 35 seconds!

In advance, thank you for any advice.