I have two kinds of objects, Beam and Sample. Sample contains 2 Beams, and I have an array of Samples. I need to store the array into the local storage, so I'm calling localStorage["samples"] = JSON.stringify(samples); but I get the error "Converting Circular Structure to JSON". My object doesn't contain itself. I also tried replacing the samples object with just 1 beam object, but get the same error, and Beam only has integer and string values in it.
Edit
Here are the objects.
function FlexuralStrengthT97(result, method, beam1, beam2, waitForCuring, averageBeams) {
this.Result = result;
this.Method = method;
this.Beam1 = beam1;
this.Beam2 = beam2;
this.WaitForCuring = waitForCuring;
this.AverageOfBeams = averageBeams;
return this;
}
function FSBeam(testingMachineId, beamAge, widthU, widthC, widthL, widthAverage, depthR, depthC, depthL, depthAverage, maxLoad, fs, psi, breakOutside) {
this.TestingMachineId = testingMachineId;
this.BeamAge = beamAge;
this.WidthUpper = widthU;
this.WidthCenter = widthC;
this.WidthLower = widthL;
this.WidthAverage = widthAverage;
this.DepthRight = depthR;
this.DepthCenter = depthC;
this.DepthLeft = depthL;
this.DepthAverage = depthAverage;
this.MaxLoad = maxLoad;
this.FS = fs;
this.PSI = psi;
this.BreakOutside = breakOutside;
return this;
}
Those seem to be constructor functions, make sure to use them with the new keyword:
var beam1 = new FSBeam();
var flex = new FlexuralStrengthT97();
Otherwise, this will be window instead of the instances scope.
Related
I am using an object for DOMString to set the DOM. I use this to pointed to the init but it shows Unexpected token this. I am learning javaScript. Please help me how to use it. Thank you very much.
let imageView = {
init: function () {
// store pointers to our DOM elements for easy access later
let DOMstrings = {
containerElem: '#cat',
nameElem: '#cat-name',
imageElem: '#cat-img',
countElem: '#cat-count'
},
this.catElem = document.getElementById(this.DOMstrings.containerElem);
this.catNameElem = document.getElementById(this.DOMstrings.nameElem);
this.catImageElem = document.getElementById(this.DOMstrings.imageElem);
this.countElem = document.getElementById(this.DOMstrings.countElem);
};
You have a comma after DOMstrings object which should be a semicolon.
Try this:
let imageView = {
init: function () {
// store pointers to our DOM elements for easy access later
let DOMstrings = {
containerElem: '#cat',
nameElem: '#cat-name',
imageElem: '#cat-img',
countElem: '#cat-count'
};
this.catElem = document.getElementById(DOMstrings.containerElem);
this.catNameElem = document.getElementById(DOMstrings.nameElem);
this.catImageElem = document.getElementById(DOMstrings.imageElem);
this.countElem = document.getElementById(DOMstrings.countElem);
}
I'm trying to make a project that searches through a block of text, then pushes certain values to the properties of an object, but whenever I put a variable inside of the ingamePrices object at near the bottom of this block of text,
var testPrompt = prompt("Let's figure out how this works");
var rawUSDValue = 0.125;
function item(craftGamePrice, craftMarketPrice, uncraftGamePrice, uncraftMarketPrice, strangeGamePrice, strangeMarketPrice, genuineGamePrice, genuineMarketPrice, vintageGamePrice, vintageMarketPrice, unusualGamePrice, unusualMarketPrice, hauntedGamePrice, hauntedMarketPrice, collectorGamePrice, collectorMarketPrice )
{
this.craftGamePrice = craftGamePrice,
this.craftMarketPrice = craftMarketPrice,
this.uncraftGamePrice = uncraftGamePrice,
this.uncraftMarketPrice = uncraftMarketPrice,
this.strangeGamePrice = strangeGamePrice,
this.strangeMarketPrice = strangeMarketPrice,
this.genuineGamePrice = genuineGamePrice,
this.genuineMarketPrice = genuineMarketPrice,
this.vintageGamePrice = vintageGamePrice,
this.vintageMarketPrice = vintageMarketPrice,
this.unusualGamePrice = unusualGamePrice,
this.unusualMarketPrice = unusualMarketPrice,
this.hauntedGamePrice = hauntedGamePrice,
this.hauntedMarketPrice = hauntedMarketPrice,
this.collectorGamePrice = collectorGamePrice,
this.collectorMarketPrice = collectorMarketPrice
}
var ingamePrices =
{
};
document.write(testPrompt);
so that it's like this
var testPrompt = prompt("Let's figure out how this works");
var rawUSDValue = 0.125;
function item(craftGamePrice, craftMarketPrice, uncraftGamePrice, uncraftMarketPrice, strangeGamePrice, strangeMarketPrice, genuineGamePrice, genuineMarketPrice, vintageGamePrice, vintageMarketPrice, unusualGamePrice, unusualMarketPrice, hauntedGamePrice, hauntedMarketPrice, collectorGamePrice, collectorMarketPrice )
{
this.craftGamePrice = craftGamePrice,
this.craftMarketPrice = craftMarketPrice,
this.uncraftGamePrice = uncraftGamePrice,
this.uncraftMarketPrice = uncraftMarketPrice,
this.strangeGamePrice = strangeGamePrice,
this.strangeMarketPrice = strangeMarketPrice,
this.genuineGamePrice = genuineGamePrice,
this.genuineMarketPrice = genuineMarketPrice,
this.vintageGamePrice = vintageGamePrice,
this.vintageMarketPrice = vintageMarketPrice,
this.unusualGamePrice = unusualGamePrice,
this.unusualMarketPrice = unusualMarketPrice,
this.hauntedGamePrice = hauntedGamePrice,
this.hauntedMarketPrice = hauntedMarketPrice,
this.collectorGamePrice = collectorGamePrice,
this.collectorMarketPrice = collectorMarketPrice
}
var ingamePrices =
{
var testVariable = "sampleString";
};
document.write(testPrompt);
it causes the "prompt" command to stop working. Does anyone know why, or how to fix it?
var ingamePrices =
{
var testVariable = "sampleString";
};
This might be an attempt at one of two things: an object literal, or block syntax which you imagine will contain testVariable. Object literals contain keys and values, they don't contain arbitrary expressions or variable definitions. As an object literal this should be
var ingamePrices =
{
testVariable: "sampleString"
};
Or possibly, if you really did want a testVariable as context for some of the contents of this object, then:
var testVariable = "sampleString",
ingamePrices =
{
blah: [testVariable, "a use of testVariable"]
};
If you were looking for block syntax, and lexical variables, then JavaScript doesn't have them. It only has global and function variables. Which means cases like this become a self-executing function, purely to provide scope:
var ingamePrices = (function() {
var testVariable = "sampleString";
...
return { blah: testVariable };
})()
I have created a custom object similar to this simplified example. My implementation gives Playlist more complex methods:
function Playlist(id) {
var _songs = [];
if(!id)
id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); });
var playlist = {
id: id,
title: "New Playlist",
clear: function(){
_songs = [];
_save();
},
songCount: function () {
return _songs.length;
},
getSongs: function () {
return _songs;
}
}
return playlist;
}
Now, I have another object, Playlists, which saves Playlist objects:
function playlists(){
var _playlists = null;
var _currentPlaylist = null;
var _save = function () {
localStorage.setItem('playlists', JSON.stringify(_playlists));
};
var _loadPlaylists = function(){
_playlists = localStorage.getItem('playlists');
try {
if (_playlists && _playlists != 'undefined')
_playlists = JSON.parse(_playlists);
}
catch(exception){
console.error(exception);
}
if(!_playlists){
_playlists = new Array();
var defaultPlaylist = new Playlist(null, null);
_playlists.push(defaultPlaylist);
_save();
}
};
var playlists = {
count: function(){
return _playlists.length;
},
getPlaylists: function(){
return _playlists;
},
getCurrentPlaylist: function(){
currentPlaylist = _currentPlaylist;
if(!currentPlaylist){
_loadPlaylists();
currentPlaylist = _playlists[0];
currentPlaylist.selected = true;
}
return currentPlaylist;
},
addPlaylist: function(playlistName){
var playlist = new Playlist(null, playlistName);
_playlists.push(playlist);
_save();
}
}
return playlists;
}
When I convert a playlist object from JSON to an object using JSON.parse I note that the Playlist object has been stripped of its methods. I believe this is because JSON.stringify does not know how to (or it does not know that it should) convert the object into JSON.
I was wondering what the proper response to this is? Is it possible to tag the methods as serializable? Or is more work required?
JSON.stringify() saves data properties, not methods. That's how it works.
If you're expecting it to save your actual javascript code, that is simply not how it's designed. If you wanted, you could add a data property that was the custom type of the object and when you read back in the object, you could use that to reattach the appropriate methods. But, that does not happen with JSON.stringify() and JSON.parse().
If you know in advance what type of object you're reading, you can create that type of object and pass it the saved JSON as an initializer.
As mentioned, stringify is designed to serialize properties, not function.
I found this blog post that goes through the process of explaining why this is the case, and finally how to preserve an object's functions through the use of the __proto__ property. Looks like the only way around it for now.
I'm taking an adventure into the depths of JavaScript and have come across a little problem that I can't get my head around.
Everything I know about programming is self taught, this problem might have some terminology behind it I have never heard of, so I don't know what it would be called.
I'll explain the problem I am experiencing.
I've been writing a framework for HTML5 canvas for displaying 2d and 3d graphics.
As you might expect, I have designed an element class, these elements have positions on the canvas which are built from a vector class I put together.
The problem I'm having is, if I make two "Text" objects, then call a function inside their position object, all the positions of the "Text" objects change to this value:
var usernameLabel = new C.Text('Username:');
usernameLabel.position.set(30,30)
var username = new C.Text('Hello World');
username.position.set(0,70)
console.log(usernameLabel.position.x) // 0 when it should be 30
I'm sure there is something I missed, I just can't figure out what.
C.Text.prototype = new C.Element();
C.Element.position = new JC.Vector();
Any help would be most appreciated!
This is my full Element class
C.elements = 0;
C.Element = function()
{
this.id = C.elements ++;
this.position = new C.Vector();
this.rotation = new C.Vector();
this.style = new C.Style();
this.children = [];
}
C.Element.prototype = {
constructor : C.Element,
addChildObject : function( o )
{
return this.children.push(o);
},
removeChildObject : function( o )
{
this.children.splice(o,1);
}
}
Text class
C.Text = function(string)
{
this.string = string || '';
}
C.Text.prototype = new C.Element();
C.Text.prototype.constructor = C.Text();
I also have more classes built from C.Element obviously, for example:
C.Rectangle = function(width, height)
{
this.style.setSize(width,height);
}
C.Rectangle.prototype = new C.Element();
C.Rectangle.prototype.constructor = new C.Rectangle();
var usernameLabel = new C.Text('Username:');
usernameLabel.position.set(30,30) // 0,70?
var username = new C.Text('');
username.position.set(0,70) // 0,70
var rect = new C.Rectangle(20,0);
rect.position.set(30,80) // 90,80?
var rect2 = new C.Rectangle(20,0);
rect2.position.set(90,80) // 90,80
From the looks of it, you are declaring position as a 'static' variable on the object, which means it will change. To make it change only on a specific object you need one of the following:
C.Element.prototype.position = new JC.Vector();
or inside a function within the object
this.position = new JC.Vector();
These declarations are for items that are specific to the object, where as the C.Element.position declaration is for something that will be the same in all instances of the object.
Update
Instead of declaring C.Text.prototype = new C.Element(). Try using C.Text.prototype = C.Element.prototype. Hopefully that will fix your problem. Instead of creating a new object to base it on, it bases it directly on the prototype of C.Element
I found the answer! Thanks for the help! The solution was to make the parent object do a call
for a reason I don't fully understand.
C.Text = function(string)
{
C.Object.call(this)
this.string = string || '';
return this;
}
C.Text.prototype = new C.Object();
C.Text.prototype.constructor = C.Text;
I have a variable with a value, let's say
var myVarMAX = 5;
In HTML I have an element with id="myVar".
I combine the id with the string MAX (creating a string myVarMAX). My question is how can I use this string to access a variable with the same name?
You COULD use eval, but if you have the var in the window scope, this is better
var myVarMAX = 5;
var id="MAX"; // likely not in a var
alert(window["myVar"+id]); // alerts 5
However Don't pollute the global scope!
A better solution is something like what is suggested in the link I posted
var myVars = {
"myVarMin":1,
"myVarMax":5,
"otherVarXX":"fred"
} // notice no comma after the last var
then you have
alert(myVars["myVar"+id]);
Since this post is referred to often, I would like to add a use case.
It is probably often a PHP programmer who gives Javascript/Nodejs a try, who runs into this problem.
// my variables in PHP
$dogs = [...]; //dog values
$cats = [...]; //cat values
$sheep = [...]; //sheep values
Let's say I want to save them each in their own file (dogs.json, cats.json, sheep.json), not all at the same time, without creating functions like savedogs, savecats, savesheep. An example command would be save('dogs')
In PHP it works like this:
function save($animal) {
if(!$animal) return false;
file_put_contents($animal.'.json', json_encode($$animal));
return true;
}
In Nodejs/Javascript it could be done like this
// my variables in NodeJS/Javascript
let dogs = [...]; //dog values
let cats = [...]; //cat values
let sheep = [...]; //sheep values
function save(animal) {
if (!animal) return false;
let animalType = {};
animalType.dogs = dogs;
animalType.cats = cats;
animalType.sheep = sheep;
fs.writeFile(animal + '.json', JSON.stringify(animalType[animal]), function (err){
if (err) return false;
});
return true;
}