Hey

This is a stupid and very noob question but lets say I have something like:

<script type="text/javascript">

/*javascript up here*/
var variable = new object("bla", "morebla");    
variable.dosomething("evenmorebla", function(key, value)
{         
alert("key is '" + key + "' and value is '" + value + "'"); 
});

alert ("alert 2 : print and use value on the outside such as here" + value);

/*javascript down here*/

</script>

How can I use/access value in that place where it says alert 2? Thank you very much.

Recommended Answers

All 42 Replies

I'm no javascript expert, but I don't think you can.
The variable value is an argument to the function, and can't be accessed from anywhere else.
But you can probably return value to an outside variable and use that in your alert.

var outsidevariable = variable.dosomething("evenmorebla", function(key, value)
{
   alert("key is '" + key ' "' and value is '" + value + "'");
   return value;
});

alert ("alert 2 : print and use value on the outside such as here: " + outsidevariable);

I thought that could not be done; didn't even go thru my head..

Javascript is so strange when it comes to its syntaxis.....

Will try tommorow....thank you!

Nope didnt work....

The entire code is:

<script type="text/javascript">

                /*
 * Copyright 2010 Nicholas C. Zakas. All rights reserved.
 * BSD Licensed.
 */
function CrossDomainStorage(origin, path){
    this.origin = origin;
    this.path = path;
    this._iframe = null;
    this._iframeReady = false;
    this._queue = [];
    this._requests = {};
    this._id = 0;
}

CrossDomainStorage.prototype = {

    //restore constructor
    constructor: CrossDomainStorage,

    //public interface methods

    init: function(){

        var that = this;

        if (!this._iframe){
            if (window.postMessage && window.JSON && window.localStorage){
                this._iframe = document.createElement("iframe");
                this._iframe.style.cssText = "position:absolute;width:1px;height:1px;left:-9999px;";
                document.body.appendChild(this._iframe);

                if (window.addEventListener){
                    this._iframe.addEventListener("load", function(){ that._iframeLoaded(); }, false);
                    window.addEventListener("message", function(event){ that._handleMessage(event); }, false);
                } else if (this._iframe.attachEvent){
                    this._iframe.attachEvent("onload", function(){ that._iframeLoaded(); }, false);
                    window.attachEvent("onmessage", function(event){ that._handleMessage(event); });
                }
            } else {
                throw new Error("Unsupported browser.");
            }
        }

        this._iframe.src = this.origin + this.path;

    },

    requestValue: function(key, callback){
        var request = {
                key: key,
                id: ++this._id
            },
            data = {
                request: request,
                callback: callback
            };

        if (this._iframeReady){
            this._sendRequest(data);
        } else {
            this._queue.push(data);
        }   

        if (!this._iframe){
            this.init();
        }
    },

    //private methods

    _sendRequest: function(data){
        this._requests[data.request.id] = data;
        this._iframe.contentWindow.postMessage(JSON.stringify(data.request), this.origin);
    },

    _iframeLoaded: function(){
        this._iframeReady = true;

        if (this._queue.length){
            for (var i=0, len=this._queue.length; i < len; i++){
                this._sendRequest(this._queue[i]);
            }
            this._queue = [];
        }
    },

    _handleMessage: function(event){
        if (event.origin == this.origin){
            var data = JSON.parse(event.data);
            this._requests[data.id].callback(data.key, data.value);
            delete this._requests[data.id];
        }
    }

};


var remoteStorage = new CrossDomainStorage("http://somewhere.com", "/server.html");
                    remoteStorage.requestValue(stringdepuntos, function(key, value){
                    alert("The value for '" + key + "' is '" + value + "'");

                    });

                    alert ("I want to access value here! " + value);
    </script>

Thanks!

Oh, I see.
Then add your own variable among those already declared in the constructor.
And in the function you simply assign value to this.<yourvariable>.
And in extension read this.<yourvariable> in the alert.

Something like:

<script type="text/javascript">

                /*
 * Copyright 2010 Nicholas C. Zakas. All rights reserved.
 * BSD Licensed.
 */
function CrossDomainStorage(origin, path){
    this.origin = origin;
    this.path = path;
    this._iframe = null;
    this._iframeReady = false;
    this._queue = [];
    this._requests = {};
    this._id = 0;
    this.val="";
}

CrossDomainStorage.prototype = {

    //restore constructor
    constructor: CrossDomainStorage,

    //public interface methods

    init: function(){

        var that = this;

        if (!this._iframe){
            if (window.postMessage && window.JSON && window.localStorage){
                this._iframe = document.createElement("iframe");
                this._iframe.style.cssText = "position:absolute;width:1px;height:1px;left:-9999px;";
                document.body.appendChild(this._iframe);

                if (window.addEventListener){
                    this._iframe.addEventListener("load", function(){ that._iframeLoaded(); }, false);
                    window.addEventListener("message", function(event){ that._handleMessage(event); }, false);
                } else if (this._iframe.attachEvent){
                    this._iframe.attachEvent("onload", function(){ that._iframeLoaded(); }, false);
                    window.attachEvent("onmessage", function(event){ that._handleMessage(event); });
                }
            } else {
                throw new Error("Unsupported browser.");
            }
        }

        this._iframe.src = this.origin + this.path;

    },

    requestValue: function(key, callback){
        var request = {
                key: key,
                id: ++this._id
            },
            data = {
                request: request,
                callback: callback
            };

        if (this._iframeReady){
            this._sendRequest(data);
        } else {
            this._queue.push(data);
        }   

        if (!this._iframe){
            this.init();
        }
    },

    //private methods

    _sendRequest: function(data){
        this._requests[data.request.id] = data;
        this._iframe.contentWindow.postMessage(JSON.stringify(data.request), this.origin);
    },

    _iframeLoaded: function(){
        this._iframeReady = true;

        if (this._queue.length){
            for (var i=0, len=this._queue.length; i < len; i++){
                this._sendRequest(this._queue[i]);
            }
            this._queue = [];
        }
    },

    _handleMessage: function(event){
        if (event.origin == this.origin){
            var data = JSON.parse(event.data);
            this._requests[data.id].callback(data.key, data.value);
            delete this._requests[data.id];
        }
    }

};


var remoteStorage = new CrossDomainStorage("http://somewhere.com", "/server.html");
                    remoteStorage.requestValue(stringdepuntos, function(key, value){
                    alert("The value for '" + key + "' is '" + value + "'");
                    this.val=value;
                    });

              //option 1
            alert ("I want to access value here! " + this.val);

            //option 2
            alert ("I want to access value here! " + val);

            //option 3
            alert ("I want to access value here! " + remoteStorage.val);

    </script>

?????

Exactly.
Option 3.

Although. On further inspection you can see that the information you're looking for can be found in the request object. (this.request).
So, if you want that value you can read that object and get the last item by using the length property.

If I'm not completely off the track, this should work.

alert("I want to access value here! " + this.request[this.request.length - 1].callback);

Nope.....did not work. I hope you can help me out furhter as this is killing me please :)

I tried that but doesnt work.

alert("hi");
alert("I want to access value here! " + this.request[this.request.length - 1].callback);
alert("bye");

Doesnt reach bye.

Have you tried debugging that line?
I know Chrome has sort of a built-in debugger. And Firefox has an addon called Firebug you can use.

No because I dont know WHAT to debug :S

I currently have this:

I currently have this:

remoteStorage.requestValue("something", function(key, value){



                valor=value;
                remoteStorage.v=value;



                    hero<?php echo $_SESSION['countforfor']; ?> =  value;
                    document.getElementById("fotop<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;
                    document.getElementById("fotog<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;
                    alert("value " + value);


                });

Which works if I put the alert. If I dont put it, its always the same value.

Using alert("I want to access value here! " + this.request[this.request.length - 1].callback); where you would like to use it, debug the code using any of the two methods I told you about and put a breakpoint on that line and create a Watch on the code that contains the value.

If the above code (this.request[yadda yadda) doesn't work, then try one of the other methods we've explored in this thread.

I apoligize if this sounds stupid but how do you add a breakpoint/watch in Chrome/Firebug? Im used to IDEs like VS and MyEclipse so I cant see any similar options.

Thanks for the help.

Searching for that debug option, I noticed in the console this:

this._requests[data.id] is undefined
this._requests[data.id].callback(data.key, data.value);

Is this normal?

NOW, if I put a alert, that error does not ocurr.......

Sometimes that's normal.
Variables and objects can be undefined until they are assigned something.

Understood :)

How do I add those breakpoints/watches? I feel dumb but I cant find a option :S

A very stripped down version of what you're trying to do:

function CrossDomainStorage() {}

CrossDomainStorage.prototype = {

    foo: function(callback) {
        callback.call(this, 1, 'bar');
    }

}

var remoteStorage = new CrossDomainStorage;

remoteStorage.foo(function(key, value) {
    alert('inside ' + value);
    this.val = value;    
});

alert('outside ' + remoteStorage.val);

The key here is to use the .call() method on the callback so you can tell it what 'this' should be. That way when you reference 'this' in the anonymous function/callback, it refers to the remoteStorage instance.

_handleMessage: function(event){
    if (event.origin == this.origin){
        var data = JSON.parse(event.data);
        this._requests[data.id].callback.call(this, data.key, data.value);
        delete this._requests[data.id];
    }
}​

Do I just copy your code or are you putting a example? I ask because I have copied and pasted so many examples (and commented them out again)

OK, it prints out "bar" on the outside because I pass bar in the foo function but obviously thats not what I want

It does what I want; Now I just need it to requestValue (run that and get the value) instead of "bar"

(Sorry for quick posting like that; Just feel like Im close and this has been such a long process)

So close......

I wasn't suggesting you copy and paste my code... it was just an example to show you what you are trying to do in it's simplest form. The only piece of code from my post that you should have copied is the _handleMessage() method. You also need to add this.val = value; to the callback function.

I'll make this easier for you....

<script type="text/javascript">

    /*
     * Copyright 2010 Nicholas C. Zakas. All rights reserved.
     * BSD Licensed.
     */

    function CrossDomainStorage(origin, path){
        this.origin = origin;
        this.path = path;
        this._iframe = null;
        this._iframeReady = false;
        this._queue = [];
        this._requests = {};
        this._id = 0;
    }

    CrossDomainStorage.prototype = {

        //restore constructor
        constructor: CrossDomainStorage,

        //public interface methods
        init: function(){
            var that = this;
            if (!this._iframe){
                if (window.postMessage && window.JSON && window.localStorage){
                    this._iframe = document.createElement("iframe");
                    this._iframe.style.cssText = "position:absolute;width:1px;height:1px;left:-9999px;";
                    document.body.appendChild(this._iframe);
                    if (window.addEventListener){
                        this._iframe.addEventListener("load", function(){ that._iframeLoaded(); }, false);
                        window.addEventListener("message", function(event){ that._handleMessage(event); }, false);
                    } else if (this._iframe.attachEvent){
                        this._iframe.attachEvent("onload", function(){ that._iframeLoaded(); }, false);
                        window.attachEvent("onmessage", function(event){ that._handleMessage(event); });
                    }
                } else {
                    throw new Error("Unsupported browser.");
                }
            }
            this._iframe.src = this.origin + this.path;
        },

        requestValue: function(key, callback){
            var request = {
                    key: key,
                    id: ++this._id
                },
                data = {
                    request: request,
                    callback: callback
                };
            if (this._iframeReady){
                this._sendRequest(data);
            } else {
                this._queue.push(data);
            }   
            if (!this._iframe){
                this.init();
            }
        },

        //private methods
        _sendRequest: function(data){
            this._requests[data.request.id] = data;
            this._iframe.contentWindow.postMessage(JSON.stringify(data.request), this.origin);
        },

        _iframeLoaded: function(){
            this._iframeReady = true;
            if (this._queue.length){
                for (var i=0, len=this._queue.length; i < len; i++){
                    this._sendRequest(this._queue[i]);
                }
                this._queue = [];
            }
        },

        _handleMessage: function(event){
            if (event.origin == this.origin){
                var data = JSON.parse(event.data);
                this._requests[data.id].callback.call(this, data.key, data.value);
                delete this._requests[data.id];
            }
        }
    };

    var remoteStorage = new CrossDomainStorage("http://somewhere.com", "/server.html");

    remoteStorage.requestValue(stringdepuntos, function(key, value){
        alert("The value for '" + key + "' is '" + value + "'");
        this.val = value;
    });

    alert("outside " + remoteStorage.val);

</script>

Copy and paste all of that and it should work :)

I wasn't suggesting you copy and paste my code... it was just an example to show you what you are trying to do in it's simplest form. The only piece of code from my post that you should have copied is the _handleMessage() method. You also need to add this.val = value; to the callback function.

I added this:

_handleMessage: function(event){
        if (event.origin == this.origin){
            var data = JSON.parse(event.data);
            //this._requests[data.id].callback(data.key, data.value);
            this._requests[data.id].callback.call(this,data.key, data.value);
            delete this._requests[data.id];
      }

to _handleMessage as you see.....

then......

var remoteStorage = new CrossDomainStorage("http://something.com", "/server.html");
                    remoteStorage.requestValue(stringdepuntos, function(key, value){


                    this.val = value;
                    remoteStorage.val=value;
    alert ("inside val val " + this.val);
    alert ("inside remotestorate val " + remoteStorage.val);

                    })

alert ("outside val " + remoteStorage.val);

and still absolutely nothing at all......

The rest of my code is exactly the same.

I have no idea what that .call is (as it is not declared anywhere) but neither is "callback" so......Im just putting what you guys comment. Thank you very much for trying to help me out :) I really appreciate it but I hope you understand that this is really frustrating....

I copied and pasted that code that you put (which I thank you very much for) and it says "outside undefined"

It says "outside undefined" but when I assign it to a element in the page, it gets it correctly BUT this only works, once again, if I put a alert. Without the alert, it stays undefined and does not set it.

Well....at least we can pretty much confirm something else is going on because if your code is suppose to work as is, then there is something else going on, more importantly, on that issue with why it works with a alert and why it doesnt work without it.

Its pretty much beyond my scope as I dont know where/what the issue could be. Should I post this also in the PHP/HTML/etc forums?

Also (although I think this is pretty obvious)

hero<?php echo $_SESSION['countforfor']; ?> = remoteStorage.val;
                    document.getElementById("fotop<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;
                    document.getElementById("fotog<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;

alert('outside ' + remoteStorage.val);

Shows undefined and does NOT work

alert('outside ' + remoteStorage.val);

hero<?php echo $_SESSION['countforfor']; ?> = remoteStorage.val;
                    document.getElementById("fotop<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;
                    document.getElementById("fotog<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;

Shows undefined and WORKS

With this code it works twice: Afterwards it repeats the second value the entire time:

remoteStorage.requestValue(stringdepuntos, function(key, value){

    this.val = value;
    remoteStorage.val=value;
});








                setTimeout(function(){
                remoteStorage.requestValue(stringdepuntos, function(key, value){

                this.val = value;
                remoteStorage.val=value;
                });
                hero<?php echo $_SESSION['countforfor']; ?> = remoteStorage.val;
                document.getElementById("fotop<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;
                document.getElementById("fotog<?php echo $_SESSION['countforfor']; ?>").src=hero<?php echo $_SESSION['countforfor']; ?>;
                },3000);
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.