/    Sign up×
Community /Pin to ProfileBookmark

Accessing a variable outside of a javascript function?

Hello

I have the following and I want to access the variable outside of that function.

The code is:

[CODE]<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(“something”, function(key, value){
alert(“The value for ‘” + key + “‘ is ‘” + value + “‘”);

});

alert (“I want to access value here! ” + value);
</script>[/CODE]

Ive tried two solutions, neither of them work:

[code]var somevar=””;
var remoteStorage = new CrossDomainStorage(“http://somewhere.com”, “/server.html”);
remoteStorage.requestValue(“something”, function(key, value){
alert(“The value for ‘” + key + “‘ is ‘” + value + “‘”);
somevar=value;
});
alert (“show somevar: ” + somevar);
alert (“I want to access value here! ” + value);[/code]

[CODE]var somevar=””;
var remoteStorage = new CrossDomainStorage(“http://somewhere.com”, “/server.html”);
somevar=remoteStorage.requestValue(“something”, function(key, value){
alert(“The value for ‘” + key + “‘ is ‘” + value + “‘”);
return value;
});
alert (“show somevar: ” + somevar);
alert (“I want to access value here! ” + value);[/CODE]

Thanks!

to post a comment
JavaScript

32 Comments(s)

Copy linkTweet thisAlerts:
@toicontienJun 14.2012 — Your remote storage is using an asynchronous process. You can stash the value in an outside variable, however the line immediately following remoteStorage.requestValue(...) is executed before the response comes back from the server.

The callback function passed into remoteStorage.requestValue() should do any subsequent processing of the value returned by the server.
Copy linkTweet thisAlerts:
@riahc3authorJun 15.2012 — Your remote storage is using an asynchronous process. You can stash the value in an outside variable, however the line immediately following remoteStorage.requestValue(...) is executed before the response comes back from the server.

The callback function passed into remoteStorage.requestValue() should do any subsequent processing of the value returned by the server.[/QUOTE]


Thank you for the reply.

Ive tried several ways using several methods (callback and everything) and I seem not to be able to get it out of there.

Could you either look over the code and please try to help me out or maybe some "Hello World" solutions where I might be able to see some kind of solution to this problem?

Thank you very much!
Copy linkTweet thisAlerts:
@toicontienJun 15.2012 — Are you getting a JavaScript error? If so, please post it.
Copy linkTweet thisAlerts:
@riahc3authorJun 15.2012 — No Javascript error.

My current code is:

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

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];
}
}

};
//continued below
[/CODE]


<i>
</i>//from above
remoteStorage.requestValue("something", function(key, value){
//alert("The value for '" + key + "' is '" + value + "'");

<i> </i> remoteStorage.v=value;

<i> </i> hero&lt;?php echo $_SESSION['countforfor']; ?&gt; = value;
<i> </i> document.getElementById("fotop&lt;?php echo $_SESSION['countforfor']; ?&gt;").src=hero&lt;?php echo $_SESSION['countforfor']; ?&gt;;
<i> </i> document.getElementById("fotog&lt;?php echo $_SESSION['countforfor']; ?&gt;").src=hero&lt;?php echo $_SESSION['countforfor']; ?&gt;;


<i> </i> });
alert("hi");
alert("I want to access value here with only reuqest! " + .request.callback);
alert("bye");


It doesnt reach "bye"
Copy linkTweet thisAlerts:
@Nemesis02Jun 15.2012 — Have you tried using a JS debugger like web developer tools in Google Chrome to debug your script to see what exactly is happening? I use it all the time to debug my own code and its really useful. In Chrome you can right click your page and click inspect and it will bring it up. You can go line by line debugging your code that way and looking at what the values are as it runs.
Copy linkTweet thisAlerts:
@riahc3authorJun 15.2012 — Have you tried using a JS debugger like web developer tools in Google Chrome to debug your script to see what exactly is happening? I use it all the time to debug my own code and its really useful. In Chrome you can right click your page and click inspect and it will bring it up. You can go line by line debugging your code that way and looking at what the values are as it runs.[/QUOTE]


Im not completely sure if this is a debugging issue as Im just doing what Ive read/been told to do. Worst part of all of this, is I dont know if its actually going to solve my problem in the end (but thats another story, Ill solve that on a seprete case)

Anyways, Ill try it, although Ive always thought that Firebug is alot better and more feature complete. That said, if you can tell me how to use the web developer tools in Chrome and Ill tell you the information I can give you to solve this problem.


Thank you very much. This problem is a complete kill and slow down.
Copy linkTweet thisAlerts:
@aj_nscJun 15.2012 — You didn't listen to toicontien, he said you cannot access the variable out there at that time because the code is asynchronous and this you are trying to alert() the value of the variable at the exact same moment that the process that is retrieving the variable is running (and not yet completed).

All code that is dependent on that variable must be included (or called from) inside the callback function.

The answer was already given to you.

Why do you think you need to access the variable outside of the callback (and before it's even populated)?
Copy linkTweet thisAlerts:
@Jeff_MottJun 16.2012 — Example:

[CODE]remoteStorage.requestValue("something", function(key, value) {
var somevar = "something";

whateverYouWantToDoNext(key, value, somevar);
});

function whateverYouWantToDoNext(key, value, somevar) {
alert("show somevar: " + somevar);
alert("I want to access value here! " + value);
}
[/CODE]
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — You didn't listen to toicontien, he said you cannot access the variable out there at that time because the code is asynchronous and this you are trying to alert() the value of the variable at the exact same moment that the process that is retrieving the variable is running (and not yet completed).

All code that is dependent on that variable must be included (or called from) inside the callback function.

The answer was already given to you.

Why do you think you need to access the variable outside of the callback (and before it's even populated)?[/QUOTE]

I need the data in "value" outside of that function. Its not a question about why, its more how...

You comment that I need the code to be inside the callback function. What exactly is my callback function in my code? I think I wouldnt have a problem putting it there (as my code is simple) but I need to know where it is.

Example:

[CODE]remoteStorage.requestValue("something", function(key, value) {
var somevar = "something";

whateverYouWantToDoNext(key, value, somevar);
});

function whateverYouWantToDoNext(key, value, somevar) {
alert("show somevar: " + somevar);
alert("I want to access value here! " + value);
}
[/CODE]
[/QUOTE]

Nope. That did not work.
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — I currently have this:

<i>
</i>remoteStorage.requestValue("something", function(key, value){



<i> </i> valor=value;
<i> </i> remoteStorage.v=value;



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


<i> </i> });

Which works if I put the alert. If I dont put it, its always the same value.
Copy linkTweet thisAlerts:
@Jeff_MottJun 18.2012 — Nope. That did not work.[/QUOTE]

You'll have to post the code you tried to run if you want us to help you find out why it isn't working.

[b]EDIT[/b]: Nevermind. Looks like you were doing just that while I made this post.

[b]EDIT[/b] [b]EDIT[/b]: Actually, what you posted doesn't look anything like what I suggested you try, so my question still stands.
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — You'll have to post the code you tried to run if you want us to help you find out why it isn't working.

[b]EDIT[/b]: Nevermind. Looks like you were doing just that while I made this post.

[b]EDIT[/b] [b]EDIT[/b]: Actually, what you posted doesn't look anything like what I suggested you try, so my question still stands.[/QUOTE]



Yes, I tried what you put ? If you want Ill do it again.........one second, while I try it and post it.
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — OK I have this Jeff Mott

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


valor=value;
remoteStorage.v=value;
assign("something",key,value);




})


function assign("something",key,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']; ?>;

}
[/CODE]


This one works the first time around but only the first time around.
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — If I put a alert in assign the following happens (Ill try to explain it as best I can):

Console: Input something

Me: 2

Console: Variable one has the value of 2

Console: Input something to create a new variable

Me: 3

Console: Variable one has the value of

Console: Variable two has the value of 3

Console: Input something to create a new variable

Me: 9

Console: Variable one has the value of

Console: Variable two has the value of

Console: Variable three has the value of 9

As you can see it only stores the last thing I input
Copy linkTweet thisAlerts:
@Jeff_MottJun 18.2012 — You actually have a syntax error in the function declaration for "assign". You can't put a string literal in the parameter list.
Copy linkTweet thisAlerts:
@Jeff_MottJun 18.2012 — As you can see it only stores the last thing I input[/QUOTE]

You'll have to post your code so we can see where your log statements are placed and what values you're logging.
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — If I do this:

[CODE]
remoteStorage.requestValue(stringdepuntos, function(key, value){


valor=value;
remoteStorage.v=value;
alert ("value in request " + value);
assign(stringdepuntos,key,value);




})


function assign(stringdepuntos,key,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);

}[/CODE]



The following happens:


Console: Input something

Me: 2

Console: Variable one has the value of 2

Console: Input something to create a new variable

Me: 3

Console: Variable one has the value of

Console: Variable two has the value of 2

(I click on the alert box that appears)

Console: Variable one has the value of

Console: Variable two has the value of 3
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — You actually have a syntax error in the function declaration for "assign". You can't put a string literal in the parameter list.[/QUOTE]
Its a variable (which contains a string). I just put it as a string literal so it can be understood. Sorry about that ?
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — You'll have to post your code so we can see where your log statements are placed and what values you're logging.[/QUOTE]

?

All my code is posted already.

If you want I can REPOST it but its all on the first page.
Copy linkTweet thisAlerts:
@Jeff_MottJun 18.2012 — The code you're posting and the output you're showing aren't jiving. Your code alerts phrases like "value" and "value in request", but you didn't post that output. And the output has phrases like "Variable one has the value of" and "Input something", but neither of those appear in the code...
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — The code you're posting and the output you're showing aren't jiving. Your code alerts phrases like "value" and "value in request", but you didn't post that output. And the output has phrases like "Variable one has the value of" and "Input something", but neither of those appear in the code...[/QUOTE]

Yes, because they are examples of what is happening.

Its like I giving a example of I have a apple and I add another apple, so there are two apples, while in reality I simply have a one plus one sum. Trying to simpliy everything giving easy explainations ?

Simply put the src in that DOM element is not being updated or only the last one is (variables 1, 2 and 3 like I mentioned)
Copy linkTweet thisAlerts:
@Jeff_MottJun 18.2012 — Yes, because they are examples of what is happening.[/QUOTE]

The problem I'm having is that we have only half the debugging information. You showed some debugging output, but not the code that generates that output. The output by itself doesn't tell us anything except that something's wrong.
Copy linkTweet thisAlerts:
@riahc3authorJun 18.2012 — The problem I'm having is that we have only half the debugging information. You showed some debugging output, but not the code that generates that output. The output by itself doesn't tell us anything except that something's wrong.[/QUOTE]

I can (try to) put the entire code if you want but its PHP/HTML/JS so..........
Copy linkTweet thisAlerts:
@riahc3authorJun 19.2012 — I dont know if thats what you need to help futher.
Copy linkTweet thisAlerts:
@criterion9Jun 19.2012 — I dont know if thats what you need to help futher.[/QUOTE]

The "final" html/scripts sent to the client should be enough. We don't need to see the PHP code since it is already executed by the time the browser sees it. You can view source on the problematic page and paste it here.
Copy linkTweet thisAlerts:
@riahc3authorJun 20.2012 — The problem is here:

_handleMessage: function(event){

if (event.origin == this.origin){

var data = JSON.parse(event.data);

/*HERE*/ this._requests[data.id].callback(data.key, data.value);
delete this._requests[data.id];
}
}



A object exists there if I put a alert (somewhere). If I dont, the object is undefinded. WHY?!?!!?!?! So very annoying....


The "final" html/scripts sent to the client should be enough. We don't need to see the PHP code since it is already executed by the time the browser sees it. You can view source on the problematic page and paste it here.
[/quote]


This is the code (JS):

[CODE]
<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 hero1="hi";



var stringdepuntos="";

var stringdepuntos=document.getElementById('xyys1').value;
var stringdepuntos=stringdepuntos.replace(/ /g,"");
var stringdepuntos=stringdepuntos.replace(/:/g,"");
var stringdepuntos=stringdepuntos.replace(/undefined/g,"");
var stringdepuntos=stringdepuntos.replace(/Type/g,"");
var stringdepuntos=stringdepuntos.replace(/Spline/g,"");
var stringdepuntos=stringdepuntos.replace(/Line/g,"");
var stringdepuntos=stringdepuntos.replace(/#/g,"");






var url = window.location.hostname;
var urlParts = url.replace('http://','').replace('https://','').split(/[/?#]/);
var domain = urlParts[0];

if (location.protocol === 'http:')
{
var remoteStorage = new CrossDomainStorage("http://"+domain+"", "/server.html");
}
else if (location.protocol == 'https:')
{
var remoteStorage = new CrossDomainStorage("https://"+domain+"", "/server.html");
}
else
{
var remoteStorage = new CrossDomainStorage("http://"+domain+"", "/server.html");
}








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


valor=value;
remoteStorage.v=value;


hero1 = value;
document.getElementById("fotop1").src=hero1;
document.getElementById("fotog1").src=hero1;
assign(stringdepuntos,key,value);


});


function assign(stringdepuntos,key,value)
{



hero1 = value;
document.getElementById("fotop1").src=hero1;
document.getElementById("fotog1").src=hero1;


}







document.getElementById("fotop1").src=hero1;
document.getElementById("fotog1").src=hero1;






</script>
[/CODE]
Copy linkTweet thisAlerts:
@riahc3authorJun 20.2012 — Is that you needed to help me out? ?
Copy linkTweet thisAlerts:
@riahc3authorJun 21.2012 — Or do you need something else?
Copy linkTweet thisAlerts:
@criterion9Jun 21.2012 — I don't see anywhere in that code that matches what your debug output was. Did you post the correct code, or were you just fudging the debug post?
Copy linkTweet thisAlerts:
@riahc3authorJun 22.2012 — I don't see anywhere in that code that matches what your debug output was. Did you post the correct code, or were you just fudging the debug post?[/QUOTE]

Ill explain the exact code then, my apoligies ?

First I have a canvas object which is basically my product. I draw different points at coordenates such as X:10 Y:7 X:8 Y: 10 etc..........When Im done, I use a function to convert that canvas into Data URI and I store it using localStorage. I do this similar to this:

localStorage.setItem("X10Y7X8Y10","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA

AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO

9TXL0Y4OHwAAAABJRU5ErkJggg=="

As you see I strip it of ":" and " " just to make sure the browser doesnt interpret it in some weird way.

I do this for each product I want. When I go to the cart, the coordenates are passed as well and I restrip them again. I search for the coordenates in localStorage and the image is displayed.
Copy linkTweet thisAlerts:
@maurycyJun 22.2012 — IT concerns me why would you like to get out from nice object oriented JS and access it from global scope? Why won't you just do actions after success/failure of sending request?
Copy linkTweet thisAlerts:
@aj_nscJun 22.2012 — It astonishes me that this thread has gone on so long when the answer has been pointed out several times.

If you are making an asynchronous request (which requesting from storage would be classified as), the only point at which you know you can access the data retrieved from the request is after success/failure - in most cases this is done through use of callback functions.

From the initial code you showed (somewhere back on the first page of this thread) you are trying to access the data outside of the callback BEFORE the request is complete.

It's not a problem to access the data outside of the callback, but you do have to wait until the request is complete, which you were not doing.

To answer another one of your questions as to why if you seemingly arbitrarily stuck in an alert() dialog then your code "worked" and if you removed the alert it didn't work - that's because the alert blocked further script execution (but not your async request). So in the time it took you to close out the alert, the async request had completed and the data was returned. If you did not block script execution (and didn't have the alert there) then the async request had not finished by the time you tried to access the data that was being returned from it and thusly you saw 'undefined'.


So after all that, for the last time in this thread I hope, you need to wait until your request has been completed before attempting to access the data.
×

Success!

Help @riahc3 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.19,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...