I have a React application which handles rooms and their statistics.
Previously, I had the code set up to pass as props to the next component:
the raw statistics (not a concern for the question)
an array of all the rooms set up as follows
I figured it would be simpler for me, though, to have the list of all rooms as an associative array where the keys of each element is the same as the ID it contains. To do that, I utilized a code similar to this in a for loop:
roomsList[rooms[v].ID] = rooms[v];
So that the result would be:
[a001: {...}, a002: {...}, ...]
I then proceeded to pass this style of array, and not the standard one with a numeric index, as a prop to the next component as such:
<StatsBreakdown stats={computedStats.current} roomsList={roomsList} />
BUT
Now, the next component sees that prop as an empty array.
Even more weirdly, if I initialize that roomsList array with a random value [0] and then do the same process, I end up with:
I cannot cycle through the array with .map, and, according to JS, the length is actually 0, it's not only Google Chrome.
Is there something I'm missing about the way JSX, JS or React work?
Your original roomsList was an array of objects, whose indices were 0,1,2 etc. roomsList[rooms[v].ID] = rooms[v]; implies you are inserting elements not using a number but an alphanumeric string. Hence your resulting array is no longer an array but an object.
So we can cycle over the object using Object.keys().
const renderRoomDets = Object.keys(roomsList).map(room => {
roomOwner = roomsList[room].owner_id;
return (
<div>
<p>{`Room Owner ${roomOwner}`}</p>
</div>
);
});
But I believe your original form is ideal, because you are reaping no special benefits from this notation.
A better alternative maybe using .find() or .findIndex() if you want iterate over an array based on a specific property.
const matchedRoom = roomsList.find(room => room.ID === 'Srf4323')
Iterate the new array using its keys not indexes.
Or even better store your data in an actual object instead of an array since you're using strings for ids.
First define your object like so:
let data = {};
Then start adding records to it. I'd suggest deleting the ID attribute of the object since you're storing it in the key of your record, it's redundant, and it won't go anywhere unless u delete the entry.
data[ID] = row;
To delete the ID attribute (optional):
row.ID = null;
delete row.ID;
Then iterate through it using
for(let key in data){}
I have this code here http://jsfiddle.net/so0rL8kj/3/
and I'm having trouble implementing a check of does input already exist in object array.
I've tried looping over json.parse(urls) something like this
if (this.url == id) {
console.log("found: " + JSON.stringify(this));
$(".order").append("<li>" + id + " ... already exists in your list.</li>");
return false;
}
But that did not stop the code from executing the localstorage.setitem save. I also tried to save as an array and then using inArray() but had no results with this functionality either.
How do I add a check to stop duplicates from user input for localstorage?
edit: working fiddle http://jsfiddle.net/so0rL8kj/4/
You can't use $.inArray() to compare a string to an array of objects.
Array would look something like:
[{"url":"someVal"},{"url":"Anotherval"}]
All $.inArray() will do is look at each object, and will never find a match since you are looking for the value of an object property in each element of the array
You can use a for loop to iterate the array and compare each url property to the string or use various array methods like Array.prototype.filter()
var alreadyExists = arrayCheck.filter(function(item){
return id ==== item.url
}).length;
This filters the array to objects that match the url to id and if it has no length there is no match
For an ember array you can simply do this:
array.get('firstObject');
to get the first object in array.
or this:
array.get('lastObject');
to get last object in array.
How do I get something by its index? similar to how it works in an ordinary javascript array:
array[index];
Looking at the documentation, you could just do var myObject = array.objectAt(someIndex);, and that will return the object at that specific index. You can check the documentation here.
array.get(index)
actually works. index can be either an integer or a string.
It also works for array-properties, ie.
this.get('myArray.1')
will return the second element in the myArray property.
I try to add elements in a particular way to the following JSON:
var data = [{"name":"google",
"ip":"10.10.10.01",
"markets":[{"name":"spain","county":"6002,6017,6018,6019,6020"},
{"name":"france","county":"6003,6005,6006,6007,6008,6025,6026,6027,6028,6029"},
{"name":"japan","county":"6004,6021,6022,6023,6024"},
{"name":"korea","county":"6000,6013,6014,6015,6016"},
{"name":"vietnam","county":"6001,6009,6010,6011,6012"}]},
{"name":"amazon",
"ip":"10.10.10.02",
"markets":[{"name":"usa","county":"10000,10001,10002,10003,10004,10005"}]},
{"name":"yahoo",
"ip":"10.10.10.03",
"markets":[{"name":"japan","county":"10000"}]}];
I want to add this element to the json:
newData = [{"name":"amazon",
"ip":"10.10.10.02",
"markets":[{"name":"mexico","county":"9000"}]}];
The result might be exactly this:
var data = [{"name":"google",
"ip":"10.10.10.01",
"markets":[{"name":"spain","county":"6002,6017,6018,6019,6020"},
{"name":"france","county":"6003,6005,6006,6007,6008,6025,6026,6027,6028,6029"},
{"name":"japan","county":"6004,6021,6022,6023,6024"},
{"name":"korea","county":"6000,6013,6014,6015,6016"},
{"name":"vietnam","county":"6001,6009,6010,6011,6012"}]},
{"name":"amazon",
"ip":"10.10.10.02",
"markets":[{"name":"usa","county":"10000,10001,10002,10003,10004,10005"},
{"name":"mexico","county":"9000"}]},
{"name":"yahoo",
"ip":"10.10.10.03",
"markets":[{"name":"japan","county":"10000"}]}];
I tried to use :
$.extend(data.markets, newData)
$.extend(true, data, newData); //this works only in the case every element is new.
but nothing works the way I pretend.
Could anyone give me a solution?
Thanks in advance.
You haven't created JSON, you've created a JavaScript literal object.
You could add this particular piece of newdata by
data[1].markets.push({"name":"mexico","county":"9000"})
Because you are dealing with javascript objects, you can write a function to check for the existence of data[n] and push data.
You have an array of objects, where each object is like the following:
var item = {"name":"...",
"ip":"...",
"markets":[ /*some objects here*/];
}
So why not just creating your custom method to insert elements? It could search in the array if an item with the same name and ip exists, and then:
If it does exist: append the markets to the existing item markets attribute (maybe you need to check again if they already exist). UPDATE:The code that #jasonscript added in his answer will do the job: once you have found where to add the market, just add it to the array. Again, maybe you'll have to check if that market was already in the array. Using jQuery it will be: $.extend(true, data[i],newData)
If it doesn't exist: just add the item to the array: $.extend(true, data,newData)
Stealing a little code from another answer:
$.each(data, function(item){
if(item.name == newData[0].name && item.ip == newData[0].ip) {
item.markets.push.apply(item.markets, newData[0].markets);
}
}
This assumes that you know that all the market items in the new object are different to the existing ones - otherwise you'd have to do a nested foreach or something. If you can change the notation of the objects a little you could think about using a dictionary-like object for Markets to make that a little cleaner.
In fact, changing data from an associative array would probably work for that too. Then you could easily check for existence with:
if(data[myNewDataName]){
//add to markets
} else {
data[myNewDataName] = myNewData;
}
I'm working on JavaScript and I have this JSON object:
var obj ={"name" : "objName",
"dynamicList" :[]};
and then I add some items to my list like this:
obj.dynamicList["someStringID"] = {"watever"};
It's important that I use a string as indexer for each item on my list (i didn't know this could be done until recently).
My only problem now is that whenever I ask for obj.dynamicList.lenght I get 0, unles I manually set the proper number... I was wondering if there's a better way to add items to my list?
Thanks!!
In Javascript, string index is not really an index. It's actually an attribute of the array object. You could set and get the value with the string index, but it's actually an empty array with some attributes. Not only .length, but also .sort(), .splice(), and other array function would not work. If there is a need to use array functions, I would use number as an index to make it a real item in the array.
If you have to use the string as an index, you couldn't rely on .length function. If there is no need to support IE prior to version 9, the Object.keys as suggested by #strimp099 should work. or you may have to create function to count the number of attributes for example:
function len(obj) {
var attrCount = 0;
for(var k in obj) {
attrCount++;
}
return attrCount;
}
and then call
len(obj.dynamicList);
Use the following the find the length of dynamicList object:
Object.keys(obj.dynamicList).length
To do this "the right way," you will have to make obj.dynamicList an object instead of an array; use {} instead of [] to set the initial value.
How to efficiently count the number of keys/properties of an object in JavaScript?
dynamiclist is an object, the length is not the length property you expect from an array.