1

I am trying to generate widget through javascript, that fetch the result from the server and display it.

This is how i am doing:

var Widgets = function( element, options ) {

    this.ele = document.getElementById( element );
    this.options = extend({}, this.options);
    extend( this.options, options );
    this._init();
};

Widgets.prototype = {
    options: {
        userKey: 'xxxxxxxxxxxxxxxxxx'
    }, 
    _init: function() {

        // Send request to Server
        this.sendRequestToServer();
    }, 

    sendRequestToServer: function() {

        var script = document.createElement('script');
        script.src = 'http://example.localhost/api/get_widget/'+this.options.userKey+'?callback=onFetchComplete';
        document.getElementsByTagName('head')[0].appendChild(script);
    }, 

    // callback not working
    onFetchComplete: function() {

    }

};

My problem is callback=onFetchComplete, my method in not callable with callback request. I know that this will work with when i call with this.onFetchComplete. Can anyone please suggest the right way to do this through the same prototyping approach?

jogesh_pi
  • 9,762
  • 4
  • 37
  • 65
  • How did you instantiate the `Widgets`? – Bergi May 30 '14 at 05:11
  • Do you know [how JSONP works](https://en.wikipedia.org/wiki/JSONP)? There is no global `onFetchComplete` variable that could be called. – Bergi May 30 '14 at 05:12
  • @Bergi this is how do i initiate `new Widgets('cf_widget_container');` – jogesh_pi May 30 '14 at 05:16
  • @Bergi is there any alternative way with prototype? – jogesh_pi May 30 '14 at 05:17
  • Yes and no. You somehow need to find a way to generate a unique global identifier for each request callback. You *might* use the instance (if its a global variable already) and directly call the prototype method, as in `?callback=mywidgets.onFetchComplete`. – Bergi May 30 '14 at 05:21

2 Answers2

1

Try :

script.src = 'http://example.localhost/api/get_widget/'+this.options.userKey+'?callback=Widgets.onFetchComplete';

I tested with this code :

Widgets = {
    options: {
        userKey: 'xxxxxxxxxxxxxxxxxx'
    }, 
    _init: function() {

        // Send request to Server
        this.sendRequestToServer();
    }, 

    sendRequestToServer: function() {

        var script = document.createElement('script');
        script.src = 'http://api.dribbble.com/players/simplebits?callback=Widgets.onFetchComplete';
        document.getElementsByTagName('head')[0].appendChild(script);
    }, 

    // callback not working
    onFetchComplete: function(data) {
        console.log(data);
    }

};

window.onload = function() {
    var w = Widgets._init();
}
Tanatos
  • 1,857
  • 1
  • 13
  • 12
  • Why does this work? What exactly did you change? Why is `Widgets` not a function any more? – Bergi May 30 '14 at 05:14
  • First of all its working because I have set the callback function to : Widgets.onFetchComplete, secondly I was getting an error the way you have created the object, so I decided to do it the old fashion way. You should also have a look at : http://www.phpied.com/3-ways-to-define-a-javascript-class/ , prototype is used to add functions to already created objects. so you first need to have Widgets = {}; then you can do Widgets.prototype.function_name = function() {}; – Tanatos May 30 '14 at 05:17
  • @Tanatos this gives me error that `Widgets.onFetchComplete` is not a function, like before i get `onFetchComplete` is not a function. – jogesh_pi May 30 '14 at 05:21
  • @Tanatos: First off, I'm not the OP :-) You have completely changed `Widgets` from a "class" to a singleton instance, which is not what you should have. Your understanding of [prototypes](https://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) seems to be flawed. – Bergi May 30 '14 at 05:24
  • @Bergi, from the code he shared the first time, he didn't post the constructor for Widgets, so I took the fastest way to check my solution. – Tanatos May 30 '14 at 05:27
  • 1
    Still, he used a `.prototype`, which clearly indicated that a constructor was existent. – Bergi May 30 '14 at 05:30
1

The browser looks in the global scope for the callback function so you would need to define onFetchComplete in the global scope. It looks quite nasty but you could do this:

sendRequestToServer: function() { var script = document.createElement('script'); window.onFetchComplete = this.onFetchComplete; script.src = http://example.localhost/api/get_widget/'+this.options.userKey+'?callback=onFetchComplete'; document.getElementsByTagName('head')[0].appendChild(script); },

This is a quick-and-dirty solution so you might want to find a more elegant solution to set scope when dealing with jsonp in pure javascript.

Community
  • 1
  • 1
Brian Hadaway
  • 1,875
  • 14
  • 23