0

I am trying to call a function which is inside a Json from outside it. I want to trigger the "next" function on button "onClick" method. Here is my code. I tried calling it by onClick={this.next}, but it is never being called by this method.

export default class PlayerLogic extends Component{

    componentDidMount() {
        var self = this;
        var player = videojs(this.refs.video, this.props.options).ready(function () {
            self.player = this;
            self.player.on('play', self.handlePlay);
        });

        player.markers({
            onMarkerReached: function () {
                player.pause();
            },

            next : function() {
                // go to the next marker from current timestamp
                console.log("reached")
                var currentTime = player.currentTime();
                for (var i = 0; i < markersList.length; i++) {
                    var markerTime = setting.markerTip.time(markersList[i]);
                    if (markerTime > currentTime) {
                        player.currentTime(markerTime);
                        break;
                    }
                }
            }
        });

    }

    render() {
        return (
            <div>
                <video {... props}>
                    <source src={this.props.src} type={this.props.type} id={this.props.id}/>
                </video>
<button onClick={this.next}>Next</button>

            </div>)

    }
};
EdG
  • 2,243
  • 6
  • 48
  • 103

2 Answers2

0

I understand that you are using React, right! Is this .jsx or .tsx? Why you don't use arrow function. It's an ES6 feature. You can do this:

next: () => {
    ...
}

Mostly, all browser are supported with ES6. You can try this in your browser console:

let foo = () => 5;
console.log(foo());

Or you can compile your code back to ES5 using babel:

https://babeljs.io/docs/learn-es2015/

The problem here is when you use function, javascript will assume that this.next is your button next method, not your player next method. Arrow function () => {} will preserve this as you did:

var self = this;
var callback = function() {
    self.doSomethingHere();
}

var player = video(...).ready(callback);

So you just has to:

let callback = () => {
    this.doSomethingHere();
}
Clite Tailor
  • 438
  • 5
  • 14
  • "Why you don't use arrow function" — Why should they? It makes no practical difference for this code. – Quentin Oct 16 '16 at 08:13
  • "You can try this in your browser console" — What does that have to do with the question? – Quentin Oct 16 '16 at 08:13
0

You have to refactor it with state further as below,

export default class PlayerLogic extends Component{

constructor() {
        super();
        this.state = {
            player : {}
        };
    }

    componentDidMount() {
        var self = this;
        var player = videojs(this.refs.video, this.props.options).ready(function () {
            self.player = this;
            self.player.on('play', self.handlePlay);
        });

        player.markers({
            onMarkerReached: function () {
                player.pause();
            },

            next : function() {
                // go to the next marker from current timestamp
                console.log("reached")
                var currentTime = player.currentTime();
                for (var i = 0; i < markersList.length; i++) {
                    var markerTime = setting.markerTip.time(markersList[i]);
                    if (markerTime > currentTime) {
                        player.currentTime(markerTime);
                        break;
                    }
                }
            }
        });

        this.setState({ player: player });
    }

    next() {
       this.state.player.next ();
    }

    render() {
        return (
            <div>
                <video {... props}>
                    <source src={this.props.src} type={this.props.type} id={this.props.id}/>
                </video>
<button onClick={this.next.bind(this)}>Next</button>
Aruna
  • 448
  • 3
  • 12
  • thanks a lot. Worked for me with a small change. I had to call this.state.player.markers.next(); insted of this.state.player.next() – EdG Oct 16 '16 at 09:24
  • What if I have a button in some other component and want to do the same thing through that button. What changes will I need? – EdG Oct 16 '16 at 09:27
  • You can use a pubsub if they both are not related to each other as in, "https://github.com/mroderick/PubSubJS". More about this on, "https://ctheu.com/2015/02/12/how-to-communicate-between-react-components/". – Aruna Oct 16 '16 at 09:37
  • can I do it using redux. I want to have these two button is some other component and want to do the same thing. Pls help me in this. – EdG Oct 19 '16 at 11:26