[SOLVED] "Not a function" error again ;)

Hi everyone,

I’m trying to write a new function to check if a string could be parsed as json. So I made this function:

IframeManager.prototype.isJson = function(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
};

and call it like that:

IframeManager.prototype.parseMessage = function(event){

     var data = event.data.data;

    // use app events to communicate with the rest of the app
    switch (event.data.type) {
        case "ParseData":
            if (self.isJSON(data)){
                console.log("PC: isJSON");
            }
            break;   
    }
};

I always get the infamous “this.isJSON is not a function” error. What I’m doing wrong? I think it has something to do with scope but I’m not sure. I tried to call it with self = this but this didn’t help either.

Many Thanks!

Can you post the full script please?

full script:

var IframeManager = pc.createScript('iframeManager');


// initialize code called once per entity
IframeManager.prototype.initialize = function() {

    // --- execute
    this.connect();
    
    // --- events
    this.app.on('iFrame:sendMessage', function(type, data){
        
        this.sendMessage(type, data);        
    }, this);    
};

IframeManager.prototype.connect = function(){
  
    // --- postMessage event handlers
    window.addEventListener("message", function(event){
        this.parseMessage(event);        
    }.bind(this));

    // --- inform parent window that we are ready
   this.sendMessage('IFrameReady');
};

IframeManager.prototype.sendMessage = function(type, data){
    if( !type ) return;

    parent.postMessage({
        type: type,
        data: data
    }, '*');
};

IframeManager.prototype.parseMessage = function(event){
    
    if (!event.data) return;
    
    var data = event.data.data;

    console.log('PC: Received message: "' + event.data.data + '" event.data.type: ' + event.data.type);
    console.log(event.data);

    // use app events to communicate with the rest of the app
    switch (event.data.type) {
        case "ParseData":
            //console.log(JSON.parse(data));
            if (self.isJSON(data)){
                console.log("PC: isJSON");
            }
            this.app.fire('ParseData', data);
            console.log("PC: this.app.fire('ParseData', data)");            
            //console.log(data);            
            break;   
        case "StartGame":      
            this.app.fire('StartGame', data);            
            console.log("PC: this.app.fire('StartGame', data)");
            break;            
    }
};



IframeManager.prototype.isJson = function(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
};

Hmm… The only issue I can see is in parseMessage

            //console.log(JSON.parse(data));
            if (self.isJSON(data)){
                console.log("PC: isJSON");
            }

Should be

            //console.log(JSON.parse(data));
            if (this.isJSON(data)){
                console.log("PC: isJSON");
            }

If that doesn’t solve it, could you put together a simple example project with the issue and someone from the community can have a closer look.

Thanks a lot!

This ( :wink: ) didn’t helped, it was a leftover from an attempt to do everything with var self = this;.

I made an example project out of it: PlayCanvas | HTML5 Game Engine
When you hover over the sphere you will get Uncaught TypeError: this.isJSON is not a function. Any ideas?

Simplify this:

    window.addEventListener("message", function(event){
        this.parseMessage(event);        
    }.bind(this));

to this:

window.addEventListener("message", this.parseMessage.bind(this));

Also, keep in mind the method’s name “isJson” vs how you call it “isJSON”.

2 Likes

Thanks! So end of story: just a stupid typo (and some unnecessary complicated code)