ReferenceError: is not defined : localStorage - javascript

So i am really confused right now, not sure if I'm being stupid or not but.. when my page loads I want to bind some localStorage to a variable called JsonData.
$(document).ready(function() {
var JsonData = localStorage.getItem(0);
.....
Here is a screen shot of my console to prove localStorage.getItem(0) has a item on page load.
Any ideas?

Because the variable JsonData is defined in a dom ready callback, making it local to that method - you are trying to access the variable from the console where the variable does not exists.
If you really want to access the variable across multiple independent scopes then declare it as a global variable, but I would recommend against it(simple doesn't like to pollute the global scope with my variables)
var JsonData = localStorage.getItem(0);
$(document).ready(function () {
});
since the data has nothing to do with the dom structure you can move out of the dom ready handler

Unless the code is paused by a breakpoint in the same scope JsonData resides, console.log operates on the global scope. JsonData lives inside the ready callback and is not accessible from the global scope, thus the error.
I suggest placing a breakpoint somewhere inside the ready handler. Then you can use console.log. In Chrome, you can pop-out the console from anywhere in dev tools by pressing ESC.

Related

Changing the current closure?

I am trying to get some old code to work properly with minimal modification. The code was written on the assumption that it would run from a particular context. I have the context object.
Original code:
function oldExample(){
console.log(window); //New Error: window is undefined
console.log(gBrowser); //New Error: gBrowser is undefined
}
New, working code:
function fixedExample(){
console.log(this.window);
console.log(this.gBrowser);
}
//Elsewhere
function loadData(context) {
fixedExample.call(context);
}
Notes:
1. loadData and oldExample are defined in separate files.
2. context has other children besides window and gBrowser; This is an example
Is there a way to transition my oldExample code to work properly without needing to stuff this. everywhere? I.e., how can I run oldExample in a different context?
The only way I know how to do this is to define the properties as variables of the current context:
var object = {gBrowser: 'test'};
function oldExample(){
console.log(gBrowser);
}
var gBrowser = object.gBrowser;
oldExample();
This example outputs 'test'
But all this does is move the property access outside of the function definition, doesn't save you anything.
You can use bind method in javascript.
fixedExample.bind (context);
Now you need not use 'this' inside fixedExample and can use window directly.

Processing.getInstanceById(id); works with one function, undefined for another?

Following http://processingjs.org/articles/PomaxGuide.html for using Processing sketches on webpages, one of my functions utilizes this perfectly:
function drawSomething() {
// some calculations
var pjs = Processing.getInstanceById('canvasID');
var number = 5 // placeholder result of calculations
pjs.drawText(number);
}
Yet with another function, drawSomethingElse, the same pjs variable definition logs:
TypeError: pjs is undefined
All the code is wrapped in docReady, and drawSomething(); is called when the page loads:
$(document).ready(function(){
// do lots of stuff
drawSomethingElse();
}
Scope in javascript works like this. If you declare a var or function inside another function it's only visible inside this function
function outerScope(){
var outerVariable = "is defined in outer scope";
function innerScope(){
var innerVariable = "is defined in inner scope";
console.log(outervariable); //innerScope can see outerVariable (through a closure)
}
console.log(innerVariable) //=undefined outerScope can't see innerVariable
console.log(outerVariable) //outerScope can still see outerVariable
}
console.log(outerScope) //= function, global scope can see outerScope
console.log(outerVariable) //=undefined but global scope can't see inside outerScope
console.log(innerScope) //= undefined, therefore it can't see innerScope
console.log(innerVariable) //=undefined and of course not into inner scope
This is true for all functions, including jQuery functions, they are no exception to this rule. So that's why you have to define a var in the scope you want the scope "layer" you want to use it. And to not pollute the global scope you wrap things into these anonymous functions, just to add a scope "layer"
This model always applies, no matter how many layers you add. You will always be able to understand the behavior. (btw always check all the things with console.log you are unsure about, it helps to track down bugs. the more precise you can answer what is wrong with your solution the better you know how to fix it)
Adapting what you know about scopes and since you didn't define Processing in the current scope you know it therefore must be in global scope, means you can open your browser console and just console.log(Processing) and maybe call the method Processing.getInstanceById() yourself in the console a few times. Maybe it's not the canvas id, maybe it's the name of your sketch that defined the name of the instance. Try it out.
Since you now know that your .pde sketch isn't loaded by the time you want to get the instance via javascript, you have a few options. The easiest would be to make the sketch part of the document, so the $(document).ready() only fires and execute your javascript when both, processing and the sketch are loaded.
Usually processing checks the custom data-processing-sources attribute on the canvas and sends a asynchronous request for the files (your sketch). But since it's asynchronous it's not part of your document loading, so the document is ready but your sketch isn't.
If you instead put the sketch code in a script tag inside the document the document won't be ready until it's loaded. You also need to set the mime type or the browser will think this is javascript and throw an error. It doesn't change anything else, it's just another way of setting up your Processing Sketch.
<script type="text/processing" data-processing-target="canvasID">
//your sketch code
</script>
<canvas id="canvasID"></canvas>
And for you to still be able to load your sketch externally here comes the slightly more confusing 3rd way to set up your sketch. Remove the whole script tag and your sketch.
Skip the data-processing-target and data-processing-sources attributes, and instead of pjs = Processing.getInstanceById write
$(document).ready(function(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "yourSketch.pde");
xhr.onload = function(){
var code = xhr.response;
var canvas = document.getElementById("canvasID")
pjs = new Processing(canvas,code);
//rest of your code
}
xhr.send();
});
Note: This technique won't work if you view your website locally from the file:// protocol
pjs scope is drawSomething function for using it in different function change your code like this
(function() {
var pjs = Processing.getInstanceById('canvasID');
function drawSomething() {
var number = 5 // placeholder result of calculations
pjs.drawText(number);
}
function someotherfunction() {
drawSomething();
}
}());
now you can use pjs anywhere in this anon function

Cannot Find JavaScript Namespace

I am trying to create namespaces in JavaScript as in the following script:
var hlAdmin = hlAdmin || {};
hlAdmin.editCompany = function (src) {
// function script
}
Then I call the function in HTML:
onclick="hlAdmin.editCompany(123)"
I get a reference error: Cannot find "editCompany".
Anyone know why?
Based on your comments I assume the following:
The equivalent script (and scoping is like):
<html><head>
</script>
var hlAdmin = hlAdmin || {};
hlAdmin.editCompany = function (src) {
// error in this script
}
</script>
</head></body>
<button onclick="hlAdmin.editCompany(123)">Caption</button>
</body></html>
In this example hlAdmin is indeed in the global scope (the root-scope of the host, called window in browsers).
If (in this example) you get reference error: Cannot find "editCompany", then one should look at other error-messages in your (browser's) error-log, because when there is a fatal error in the function for hlAdmin.editCompany, then that function will not be created (hence .editCompany becomes a property that points to undefined instead of a method that points to the function OR .editCompany doesn't even exist (depending on engine/error)).
To investigate if you indeed have a scoping-problem you could test this by: window['hlAdmin'] || (window['hlAdmin']={}); (or some equivalent variant). If that made the code work, then it seems you have some scoping-problem.
Hope these steps help someone in the future.
It's generally considered bad form to mix inline javascript and non-inline. The preferred way to do this would be to keep all the javascript in one place using an event handler:
window.hlAdmin = window.hlAdmin || {};
window.hlAdmin.editCompany = function (src) {
// function script
}
document.getElementById('yourElementId').onclick = function() {
hlAdmin.editCompany(123);
};
To more specifically address the issue: One thing that could cause this issue is if the hlAdmin object is not ending up in the global scope. You stated that this declaration is "at the top of the JavaScript file", but if it's in any kind of function (such as a function set to window.onload, or the jQuery $(function() { ... });) it would not end up in the global scope when declared as a var. A variable declared with var will only end up globally scoped if it's in the root scope, outside of any kind of function. If rather than using var hlAdmin you instead use window.hlAdmin, this will make sure that even if you're inside a document ready function or something similar, you're creating your hlAdmin in the global context, which will fix the problem if it is in fact an issue of scope.
I found the problem.
The browsers (at least Aurora and Chrome) are dropping the namespace in the onclick attribute. When you look at the browser html the namespace has just disappeared from the markup.

javascript: can not use global variable in a function, to navigate the dom

beginner here...
what am i missing?
i define a global variable that is a reference to an html element:
var x=document.getElementById("xxx1");
then, inside a function a try to reference that variable to navigate the dom:
x.innerHTML="dsfgfdgdf";
...doesn't work; if i define the variable inside the function it works, but i don't see how it's a scope problem... working with global variables inside functions works fine IF i don't use them in a dom context (object.property)
thanks
It's not a scope problem.
The most likely reason is that the element doesn't exist yet when you create the variable. You have to put the script element that creates the variable after the element that you want to access, as the code will run while the page is loading.
Another alternative is to declare the variable globally, and set it from the onload event that runs after the page has loaded:
<script>
var x;
function init() {
x = document.getElementById('xxx1');
}
</script>
<body onload="init();">
Is the getElementById executed before the DOM is loaded? (you should wait for domready or onload)
Is it possible that you overwrite the value in some other function?
I think the problem may be that if you declare that variable globally, when that line is evaluated the DOM is not totally loaded and therefore the element is not accessible.
When you declare it in the function, the variable will only be created when you call that function, when the DOM will mostly likely already be fully loaded.
Maybe your page is not fully loaded when you're calling getElementById.
Make sure you create the global variable x when the page has finished loading. Most libraries has a way to handle that, jQuery for example has the "ready"-function. If you dont want to use any libraries, you can always create the variable when the body-element calls the onload-event.
jQuery-style:
$(function(){
// create X here
})
body onload style:
<body onload="aFunctionThatCreatesYourVariable()">

TypeError: Result of expression 'printWindow' [undefined] is not an object

I'm trying to create hidden iframes in my page dynamically to load 3 other pages so that i can grab all the HTML and combine them into 1 in a new window.
However i'm stuck at this.
tHe frames are created fine.
But whenever the javascript runs to the part of
var printWindow="";
function openNewWindow()
{
printWindow = window.open("","");
printWindow.document.open();
printWindow.document.write(HTMLfromFrames);
printWindow.document.close();
}
i get this error:
TypeError: Result of expression 'printWindow' [undefined] is not an object.
but if i generate a button to call this function seperately, it works fine.
however i need it to run all in one click event
Anybody has any idea what's wrong?
Thanks!
It looks to me like a scoping problem. The scope of your printWindow object ends when openNewWindow returns; in other words, the variable only exists inside that function and disappears as soon as the function ends. Remove the var to make the variable available globally (considered bad form) or declare the variable elsewhere in your code and make sure it's available to openNewWindow when it executes.
oh i solved it. SOmehow i declared as a global var
then declare the obj earlier in the method.
printWindow = window.open("","");
still not sure why i can't declare it after i dynamically create my iframes.
Thanks for the help!:D

Categories

Resources