I've got a Calendar. Inside its code there's an Object and a JSON to it, which contains several properties such as
[{"Date":"17-3-2015","Event":"Test drive","Participants":"John, George","Description":"Testing a new F30"},
{"Date":"17-3-2015","Event":"Football match","Participants":"FCSM vs FCKK","Description":"New season start"},
{"Date":"25-3-2015","Event":"Jane's Birthday","Participants":"Jane, John, Richard, Alice","Description":"Celebration with my friends"}]
But since that data is in localStorage I retrieved it via
var existEvents = JSON.parse(localStorage.getItem('events'));
for(i=0; i<existEvents.length; i++) {
var item = localStorage.getItem(localStorage.key(i));
console.log(item);
};
existEvents = every new event in my Calendar
console.log(item); returns me the data typed above.
What I need is to retrieve every Date value (= key). So I pretend that
item.Date
must work, but it doesn't. As well as
item[0].value
I tried it after having read this question + answers
Access / process (nested) objects, arrays or JSON
What am I doing wrong? Please, help!
A good way to use the Array.ForEach(), where it can be also used to loop on objects having the value as the first parameter and the key (if exists) in the second. In your example the for each takes this array, and loops on it retrieving one object at a time.
This object has a Date key in it, so you can access it using the obj.key. However, it is always good to use the .hasOwnProperty to check if the key exists first.
You can also use the forEach to loop through the object keys and then you will be able to have the obj/key. For example, looping on every obj from the array loop will give you obj => 17-3-2015 | key => Date ... etc.
var x = [{"Date":"17-3-2015","Event":"Test drive","Participants":"John, George","Description":"Testing a new F30"},
{"Date":"17-3-2015","Event":"Football match","Participants":"FCSM vs FCKK","Description":"New season start"},
{"Date":"25-3-2015","Event":"Jane's Birthday","Participants":"Jane, John, Richard, Alice","Description":"Celebration with my friends"}];
x.forEach(function(obj,key){console.log(obj.Date) });
Your code can be:
JSON.parse(localStorage.getItem('events')).forEach(function(obj,key){console.log(obj.Date) });
I don't think you need to be going back into localstorage inside your for loop since you already have all of your data in the variable existEvents.
var existEvents = JSON.parse(localStorage.getItem('events'));
for(i=0; i<existEvents.length; i++) {
var item = existEvents[i];
console.log(item);
};
The HTML5 LocalStorage is an associative array storage with the getItem function grabbing one of the items. So,
localStorage.getItem ("somekey")
returns whatever variable somekey was set to. In your code snippet, the variable you are storing in the localStorage is a String that happens to be in JSON form. JSON.parse () turns that JSON into the actual array represented by the String you've stored.
var existEvents = JSON.parse (localStorage.getItem ('events'));
for (var i = 0; i < existEvents.length; i++) {
var item = existEvents [i];
console.log(item);
};
existEvents is an Array object so you can access it like normal. After you've retrieved it from localStorage and parsed it, you no longer need to access localStorage.getItem.
Related
I have an array with the name data containing objects like so:
[{"timeslot":"6am-7am","Monday":5},{"timeslot":"7am-8am","Monday":0},{"timeslot":"8am-9am","Monday":10}]
Each object contains two key-value pairs. I need to create two new arrays:
an array, timeslots, containing each value associated with the "timeslot" key
an array, numUsers, containing each integer value associated with the "Monday" key
Here is my Javascript:
var timeslots = [];
var numUsers = [];
var keys = Object.keys(data[0]);
var today = keys[1];
for(var i in data) {
timeslots.push(data[i].timeslot);
numUsers.push(data[i].today);
}
The first line of the for loop works, and returns the following timeslots array:
["6am-7am", "7am-8am", "8am-9am"]
The second line, however, returns an array of undefined elements.
My problem is, the second key value of the objects in the data array varies. Each object will contain the same day of the week, but this day can be any one of "Monday" through "Sunday".
How can I reference it dynamically?
You can access object value using square brackets notation in the same way as you use it with i:
numUsers.push(data[i][today]);
N.B. However, your code has several very important problems that will eventually bring you errors. One of the most visible is that you rely on the order of the object properties and retrieve an array of keys with Object.keys, setting the second key as the value of today variable. Your mistake is that in different systems and browsers the code like Object.keys(obj)[1] may return different results, as object properties in JavaScript don't have order. Also, you shouldn't use for .. in statement to iterate arrays, instead utilise simple for (var i = 0, len = arr.length; i < len; i++) loop. And finally, don't forget, that data array may contain zero items, so your code data[0] will raise an error. I would suggest you to reconsider the business logic of your application and probably to rewrite it to make it more reliable.
You need this:
numUsers.push(data[i][Object.keys(data[i])[1]]);
I'm creating a game bot on telegram using node js.
Currently I'm facing a problem on shared variable (module.exports). I'm storing some of the data on the variable. And the problem is, the shared variable index always change. For example, please refer to my code below
var sharedVar = [];
createNewRoom = function(res) {
var index = sharedVar.length;
sharedVar.push({ groupId : res.chat.id }); // every time this function is invoked, it will create a new array inside sharedVar object
//Here comes the problem, it's about the index,
//because I'm using sharedVar to store arrays, then it will become a problem,
//if one array is deleted (the index will change)
var groupId = sharedVar[index].groupId; // it runs OK, if the structure of array doesn't change, but the structure of array change, the index will be a wrong number
}
As you can see, i got callGameData function, when i call it, it will show the last value of sharedVar, it's supposed to show the current room values / data.
As i mention on the code above, it's all about the dynamic array in the sharedVar object, the index will change dynamically
Any thoughts to tackle this kind of issue? I was thinking about using a new sharedVar object everytime the createNewRoom function is invoked, but the thing is, i have to use sharedVar in many different function, and i still can't figure it out on using that method.
EDIT
This is the second method
var gameData = undefined;
createNewRoom = function() {
this.gameData = new myConstructor([]); // it will instantiate a new object for each new room
}
myConstructor = function(data) {
var _data = data;
this.object = function() {
return _data;
}
}
callGameData = function() {
console.log(gameData);
}
An array is fundamentally the wrong data type to use if you want to keep indices the same even in the face of removing entries.
A better method is to use properties of an object. For example:
var roomCache = { nextId: 1 };
createNewRoom = function(res) {
roomCache[roomCache.nextId++] = {groupId: res.chat.id}; // Add a new object to the cache and increment the next ID
}
After adding two elements, you'll have the rooms in roomCache[1] and roomCache[2] - if you want to start at zero just change the original value of nextId. You can delete elements in this object and it won't shift any keys for any other objects - just use delete roomCache[1] for example to get rid of that entry.
This assumes there isn't a better ID out there to use for the cache - if, for example, it made more sense to lookup by res.chat.id you could certainly use that as the key into roomCache rather than an auto-incrementing number. Here's how it would look like to cache the values by the group ID instead:
var roomCache = { };
createNewRoom = function(res) {
roomCache[res.chat.id] = {groupId: res.chat.id}; // Assumes res.chat.id is not a duplicate of an already cached obhect
}
Now you could just look up by group ID in the cache.
Yes, it's definitely a problem cause you are not keeping track of the index in a logical way, you are relying on position on the array which it changes, you need something that doesn't change over time to keep consistency and supports deletition of the element without affecting the rest of the elements. You could use mongo to store the generated rooms by id or maybe redis or some kind of key value pair database to store that kind of information.
Newbie here...be nice.
I have an empty object that will get pushed into an array.
listView = {};
I add properties to it.
listView.code = code;
listView.description = description;
I push the results object into an array.
listy.push(listView);
Each time I enter a new selection in step #2 it overwrites the object instead of adding the new object properties to the array. It also increments the index by one, so it just repeats...
[{"code":"I77.812","description":"Thoracoabdominal Aortic Ectasia"}]
[{"code":"I77.811","description":"Abdominal Aortic Ectasia"},{"code":"I77.811","description":"Abdominal Aortic Ectasia"}]
[{"code":"I06.1","description":"Rheumatic aortic insufficiency"},{"code":"I06.1","description":"Rheumatic aortic insufficiency"},{"code":"I06.1","description":"Rheumatic aortic insufficiency"}]
The array should contain three different objects. But instead it has three copies of the newly added one...
How should I be adding the new choice objects so that they don't get overwritten?
You are always adding a reference to the same object, and changing that same object, instead of adding new objects. See this:
var a = [];
var o = {};
for (var i = 0; i < 5; i++) {
o.id = i;
a.push(o);
}
a
// => [{"id":4},{"id":4},{"id":4},{"id":4},{"id":4}]
But
var a = [];
for (var i = 0; i < 5; i++) {
var o = {};
o.id = i;
a.push(o);
}
a
// => [{"id":0},{"id":1},{"id":2},{"id":3},{"id":4}]
The difference is, the second code always makes a new object that is distinct from all other objects already in the array.
As a metaphor, imagine a theatre director in casting. He turns to an actor, says "You... you'll be Romeo.". Then he looks at the same actor, says "You... you'll be Mercutio. Here, Mercutio, take this sword. Romeo... who told you to get a sword?!?" completely failing to realise that, if Romeo and Mercutio are the same person, if one of them picks up a sword, the other does it too.
Seeing as you declared yourself a 'newbie' i figured i'd take a bit more time explaining. When you push an object to an array, you don't copy the object. You just tell the array where to find the object (a reference). If you push the same object 3 times, the array just has 3 indexes at which it finds the same object. There's several ways around this, the easiest being that you declare the variable inside the loop
for (var i=0;i<3;i++){
var listView = {};
listView.id = i;
listy.push(listView);
}
This way listView is a different reference each time. The other way is to create a new object when you push
listy.push({id:listView.id, description:listView.description});
which works because simple variables are 'copied' into the array and not referenced.
your assignment of the properties of an object are simply replacing the existing properties. wh en you push the object in the array by name, you are push a reference to the object and not a value. This is why all the elements in the array are the same. You need to create a new object every time you push. Something like this should work for you.
listy.push({code:code, description:description});
try this :
listy.push({
code:listView.code,
description : listView.description
})
In my code I have used pass by value.
In your code , you are using Objects which are passed by reference .
You are adding same reference again and again so at the end you will get an array having all the values of same object .
To understand more about pass by value and pass by reference you can reffer this link :
Pass Variables by Reference in Javascript
Can I somehow push the key:vale pairs to a JavaScript array so that I can later use them without indices even if I don't know what order I'll grab them in? I mean, such code would work:
var test = [];
test.push({key1: 5});
test.push({key2: 7});
console.log(test[0].key1);
But let's say I don't always receive the keys in that order and would like the last line to just be console.log(test.key1);, without the need to index it. Can I somehow push the pairs in such a way that later I only need to specify the key for which I want a value, and not an index under which it resides?
Yes...
var test = {};
test.key1 = 5;
test.key2 = 7;
instead of push, use an object and assing key1 to that like this: test.key1 = 5
but now it can't work as array
I know this isn't the best way to do it, but I have no other choice :(
I have to access the items in JSONObject by their index. The standard way to access objects is to just wirte this[objectName] or this.objectName. I also found a method to get all the fields inside a json object:
(for (var key in p) {
if (p.hasOwnProperty(key)) {
alert(key + " -> " + p[key]);
}
}
(Soruce : Loop through Json object).
However there is no way of accessing the JSONfields directly by a index. The only way I see right now, is to create an array, with the function above, get the fieldname by index and then get the value by fieldname.
As far as I see it, the p (in our case the JSON file must be an iteratable array to, or else the foreach loop wouldn't work. How can I access this array directly? Or is it some kind of unsorted list?
A JSON Object is more like a key-value-map; so, yes, it is unsorted. The only way to get around is the index->property name map you've already mentioned:
var keysbyindex = Object.keys(object);
for (var i=0; i<keysbyindex.length; i++)
alert(object[keysbyindex[i]]);
But why would you need these indexes? A unsorted map also has no length property, as an Array had. Why don't you use the for-in-loop
var counter = 0; // if you need it
for (var key in object) {
alert(object[key])
counter++;
}
? If you have a parsed JSON object, i.e. a plain JS Object, you won't have to worry about enumerable prototype properties.
Based on Bergis anserwer this is my solution:
var keysbyindex = Object.keys(this);
alert(this[keysbyindex[index]]);
return this[keysbyindex[index] || ""];
However, I think (not tested) it's extremly bad regaring performace and shouldn't be used! But desperate times require desperate measures.....
I don't think you can actually achieve this without creating your own parsing of JSON. You're writing that you want to go trough a JSON-object, but what you're actually trying to do is go trough a plain old Javascript object. Json is simply a string-representation used to transfer/store said object, and in here lies the main problem: the parser that transforms the string into an actual object (ie. the browser in most cases) can chose to ignore the order it finds the properties if it want to. Also, different browsers might have different approaches to parsing JSON for all you know. If they simply use a hash-map for the object that it's simple to loop through it, but the order won't be dependent on the order of the keys in the file, but rather the keys themselves.
For example, if you have the json {"b":"b","a":"a"} and do the for in loop, under some implementations you might end up with a comming first, and in others you might end up with b.
var jsn = {keyName: 'key value result come here...'};
var arr = jsn ? $.map(jsn, function (el) { return el }) : [0];
console.log(arr[0])
$('.result').text(arr[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="result"></span>