Creating Objects inside objects using a Constructor - javascript

In the below code I am trying to create an object named "portfolio" inside which
I want to create other objects that contain the properties "stockvalue" and "price"?
var portfolio_create = function(stock,stockvalue,price)
{
for(i in stock)
{
this[stock[i]] = stock[i];
this[stock[i]]["stockvalue"] =stockvalue[i];
this[stock[i]]["price"]=price[i]
}
}
var portfolio = new portfolio_create(["ibm","tcs"],[23,34],[34,45]);
var stock_market = portfolio;
alert(portfolio["ibm"]["stockvalue"]); // undefined
Why does the alert return "undefined" and not 23?
Thnaks in advance.

var portfolio_create = function (stock, stockvalue, price) {
for (var i = 0, len = stock.length; i < len; i++) {
this[stock[i]] = {};
this[stock[i]]["stockvalue"] = stockvalue[i];
this[stock[i]]["price"] = price[i];
}
}
var portfolio = new portfolio_create(["ibm", "tcs"], [23,34], [34,45]);
Don't use for..in for arrays.
this[stock[i]] = stock[i]; replace to this[stock[i]] = {};.
Example

I think there is a little confusion here, between objects and variables.
You can create a real JavaScript class portfolio, which contain a collection of another class stock, which contain 2 variables value and price.
In your portfolio class, you can add a AddStock methode, and a GetStock.
Look at JavaScript Classes, I think you will find your hapiness.
Steeve

And try to use libs like underscore or lodash to get rid of these for loops (each). It is much nicer and more functional.
A little bit shorter:
this[stock[i]] = { stockvalue: stockvalue[i], price: price[i] };

Related

Create variables based on array

I have the following array and a loop fetching the keys (https://jsfiddle.net/ytm04L53/)
var i;
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
for (i = 0; i < feeds.length; i++) {
var feed = feeds[i];
alert(feed.match(/\d+$/));
}
The array will always contain different number of keys, What I would like to do is either use these keys as variables and assign the value after the : semicolon as its value or just create a new set of variables and assign the values found on these keys to them.
How can I achieve this? so that I can then perform some sort of comparison
if (test_user > 5000) {dosomething}
update
Thanks for the answers, how can I also create a set of variables and assign the array values to them? For instance something like the following.
valCount(feeds.split(","));
function valCount(t) {
if(t[0].match(/test_user_.*/))
var testUser = t[0].match(/\d+$/);
}
Obviously there is the possibility that sometimes there will only be 1 key in the array and some times 2 or 3, so t[0] won't always be test_user_
I need to somehow pass the array to a function and perform some sort of matching, if array key starts with test_user_ then grab the value and assign it to a define variable.
Thanks guys for all your help!
You can't (reasonably) create variables with dynamic names at runtime. (It is technically possible.)
Instead, you can create object properties:
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
var obj = {};
feeds.forEach(function(entry) {
var parts = entry.split(":"); // Splits the string on the :
obj[parts[0]] = parts[1]; // Creates the property
});
Now, obj["test_user_201508_20150826080829.txt"] has the value "12345".
Live Example:
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
var obj = {};
feeds.forEach(function(entry) {
var parts = entry.split(":");
obj[parts[0]] = parts[1];
});
snippet.log(obj["test_user_201508_20150826080829.txt"]);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
You can do it like this, using the split function:
var i;
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
for (i = 0; i < feeds.length; i++) {
var feed = feeds[i];
console.log(feed.split(/[:]/));
}
This outputs:
["test_user_201508_20150826080829.txt", "12345"]
["test_user_list20150826", "666"]
["test_list_Summary20150826.txt", "321"]
Use the split method
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
feedMap = {}
for (i = 0; i < feeds.length; i++) {
var temp = feeds[i].split(':');
feedMap[temp[0]] = temp[1];
}
Yields:
{
"test_user_201508_20150826080829.txt":"12345",
"test_user_list20150826":"666",
"test_list_Summary20150826.txt":"321"
}
And can be accessed like:
feedMap["test_user_201508_20150826080829.txt"]
Here is a codepen
it is not very good idea but if you really need to create variables on-the-run here's the code:
for (i = 0; i < feeds.length; i++)
{
var feed = feeds[i];
window[feed.substring(0, feed.indexOf(":"))] = feed.match(/\d+$/);
}
alert(test_user_201508_20150826080829)
Of course you cannot have any variable-name-string containing banned signs (like '.')
Regards,
MichaƂ

Javascript - use an array for object names then grab properties using a loop

Going crazy trying to do this so I thought I'd get help. I have an array like this:
OBJECTS = ["mainmenu","mainviewer","mainsearch"];
Each of these is an object like this:
mainmenu = {width:250,height:250,backgroundcolor:red};
mainviewer = {width:250,height:250,backgroundcolor:green};
mainsearch = {width:250,height:250,backgroundcolor:blue};
Now the crux of it ... I'm simply trying to get the properties like this:
for (var item in OBJECTS) {
var name = OBJECTS[item];
console.log("the width of "+name+" is "+name.width);
}
The console logs back to me:
the width of mainmenu is undefined
Any help greatly appreciated ...
Your OBJECTS array is an array of strings. It's not an array of objects.
Perhaps you meant it to be this:
var mainmenu = {width:250,height:250,backgroundcolor:"red"};
var mainviewer = {width:250,height:250,backgroundcolor:"green"};
var mainsearch = {width:250,height:250,backgroundcolor:"blue"};
var objects = [mainmenu, mainviewer, mainsearch];
FYI, I also had to put quotes around the color names because symbols like red are not defined.
And, if you want to iterate this with a name, you could do this:
var mainmenu = {name: "mainmenu", width:250,height:250,backgroundcolor:"red"};
var mainviewer = {name:"mainview", width:250,height:250,backgroundcolor:"green"};
var mainsearch = {name: "mainsearch", width:250,height:250,backgroundcolor:"blue"};
var objects = [mainmenu, mainviewer, mainsearch];
objects.forEach(function(item) {
log("the width of "+item.name+" is "+item.width);
});
or, a traditional for loop:
for (var i = 0; i < objects.length; i++) {
var item = objects[i];
console.log("the width of "+item.name+" is "+item.width);
});
Working demo: http://jsfiddle.net/jfriend00/abwgjed2/
Note: it is a bad idea to iterate arrays with the syntax for (item in objects). This iterates all properties of the item object, not just array elements. If there are ES5/ES6 polyfills being used, there may be some extra enumerable properties that will show up in the for (item in objects) iteration. Either use .forEach() or for (var i = 0; i < objects.length; i++).
here is demo
var OBJECTS =
{
mainmenu : {width:250,height:250,backgroundcolor:'red'},
mainviewer : {width:250,height:250,backgroundcolor:'green'},
mainsearch : {width:250,height:250,backgroundcolor:'blue'}
}
for (var item in OBJECTS) {
var name = OBJECTS[item];
console.log("the width of "+item+" is "+name.width);
}

accessing nested properties based on structure

Could anyone please give me an alternate syntax to the following
var id = '-JLxSeCPUCVN13FxifTY';
var ResultsContainer = results[id];
var i=0;
for(var k in ResultsContainer)
{
var TheArrayOfObjectsThatIneed = ResultsContainer[Object.keys(ResultsContainer)[i]];
console.log(TheArrayOfObjectsThatIneed);
//loop the TheArrayOfObjectsThatIneed do the processing
i++;
}
as you see in the image i have an array within an object within an object and i have no idea what the property names are but the structure is always the same {results:{id:{idthatidontknow:[{}]}}} and all i need is to access the arrays
the above code is working nicely but i am new to javescript and i was wondering if there is a nicer syntax and if i am doing it the right way
Perhaps something like this?
var id = '-JLxSeCPUCVN13FxifTY';
var ResultsContainer = results[id];
for(var k in ResultsContainer) {
if (ResultsContainer.hasOwnProperty(k)) {
var TheArrayOfObjectsThatIneed = ResultsContainer[k];
console.log(TheArrayOfObjectsThatIneed);
//loop the TheArrayOfObjectsThatIneed do the processing
}
}

JavaScript stop referencing object after pass it to a function

I know JavaScript passes Objects by reference and thus I'm having a lot of trouble with the following code:
function doGradeAssignmentContent(dtos) {
var x = 5;
var allPages = [];
var stage = new App.UI.PopUpDisplay.PopUpStageAssignmentGrader(null, that);// pass launch element
for(var i = 0; i < dtos[0].result.students.length; ++i) {
var pagesSet = [];
for(var j = 0; j < dtos[0].result.questions.length; ++j) {
var questionObject = jQuery.extend(true, {}, new Object());
questionObject = dtos[0].result.questions[j];
if(dtos[0].result.students[i].answers[j].assignmentQuestionId === questionObject.questionId) {// expected, if not here something is wrong
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
questionObject.pointsReceived = dtos[0].result.students[i].answers[j].pointsReceived;
} else {
var theAnswer = findAssociatedStudentAnswer(questionObject.questionId, dtos[0].result.students[i].answers[j]);
if(theAnswer !== null) {
questionObject.answer = theAnswer.studentAnswer;
questionObject.pointsReceived = theAnswer.pointsReceived;
} else {
alert("Unexpected error. Please refresh and try again.");
}
}
pagesSet[pagesSet.length] = new App.UI.PopUpDisplay.StageAssignmentGradingPages[dtos[0].result.questions[j].questionType.charAt(0).toUpperCase() + dtos[0].result.questions[j].questionType.slice(1) + "QuestionAssignmentGradingPage"](j + 1, questionObject);
}
var studentInfo = {};
studentInfo.avatar = dtos[0].result.students[i].avatar;
studentInfo.displayName = dtos[0].result.students[i].displayName;
stage.addPageSet(pagesSet, studentInfo);
}
stage.launch();
}
First let me show you what the result (dtos) looks like so you can better understand how this function is parsing it:
The result (dtos) is an Object and looks something like:
dtos Array
dtos[0], static always here
dtos[0].result, static always here
dtos[0].questions Array
dtos[0].questions.index0 - indexN. This describes our Questions, each one is an Object
dtos[0].students Array
dtos[0].students[0]-[n].answers Array. Each student array/Object has an Answers array. Each student will have as many elements in this answers Array that there were questions in dtos[0].questions. Each element is an Object
Now what we do in this here is create this Object stage. Important things here are it has an array called "this.studentsPages". This array will ultimately have as many entries as there were students in dtos[0].students.
So we loop through this for loop disecting the dtos array and creating a pagesSet array. Here comes my problem. On the first iteration through the for loop I create this questionObject element. I also have tried just doing var questionObject = {}, but what you see now was just an attempt to fix the problem I was seeing, but it didn't work either.
So at the end of the first iteration of the outer for loop I call stage.addPageSet, this is what happens here:
var pageObject = [];
pageObject["questions"] = pageSet;
pageObject["displayName"] = studentInfo.displayName;
this.studentsPages[this.studentsPages.length] = pageObject;
if(this.studentsPages.length === 1) {// first time only
for(var i = 0; i < pageSet.length; ++i) {
this.addPage(pageSet[i]);
}
}
The important thing to take notice of here is where I add pageObject on to this.studentsPages which was an empty array before the first call. pageObject now has pageSet plus a little bit more information. Remember, pageSet was an Object and thus passed by reference.
On the next iteration of the for loop, when I hit this line:
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
It goes wrong. This changes the local copy of questionObject, BUT it also changes the copy of questionObjec that was passed to addPageSet and added to the studentsPages array in the first iteration. So, if I only had 2 students coming in, then when all is said and done, studentsPages hold 2 identical Objects. This should not be true.
The problem is questionObject in the doGradeAssignmentContent function is keeping a reference to the Object created on the previous iteration and then overrides it on all subsequent iterations.
What can I do to fix this?
Thanks for the help!
With out having looked at it too closely I believe you need to change the following:
// Before:
var questionObject = jQuery.extend(true, {}, new Object());
questionObject = dtos[0].result.questions[j];
// After:
var questionObject = jQuery.extend(true, {}, dtos[0].result.questions[j]);
I didn't look too closely if there are other instances in the code where this needs to be applied, but the core concept is to utilize jQuery's deep copy to generate a duplicate of the object you do not wish to retain a reference to.

how do I name objects dynamically and use object constructor in javascript?

I'm pulling data with Ajax that changes every day. I want to package the data into objects that have unique names. Currently I created a constructor that looks like something like this:
function myObject(Id,thing1,thing2,thing3)
{
this.Id = Id;
this.thing1 = thing1;
this.thing2 = thing2;
this.thing3 = thing3;
}
then I push that to an array in a loop like this
for(var i=0; i<data.length; i++)
{
array.push(new myObject(value1,value2,value3,value4));
}
This works fine for what I'm doing but I just get an array with [object,object,object,object] inside of it which I can access with array[0] , array[1], etc.
but now I want to store those objects in firebase and would need to reference them so how could I have them named uniquely?
normally you would do
var thingid1 = new myObject(value1,value2,value3,value4));
var thingid2 = new myObject(value1,value2,value3,value4));
but this is all being created on the fly and sometimes there is 1 object created and sometimes 10.
I'm new at this and I've looked everywhere so any help would be appreciated.
If your Id (value1) is unique...
var myObjectContainer = {};
for(var i=0; i<data.length; i += 1)
{
myObjectContainer[value1] = new MyObject(value1,value2,value3,value4);
}

Categories

Resources