This might be a noob question, but I'm wondering if there's a way to select a json object without having to loop through key value pairs. I've done similar things with e4x, but I'm not sure how to do it syntactically for js. For example
var data = { "objects":[
{"foo":"x","bar":"a"},
{"foo":"y","bar":"b"}
]}
So instead of a for loop, some way to declare
var someObject = data.objects[where objects.foo == x]
You may do that w/o manually iterate over data, but some code should iterate over object anyway (so doesn't expect lightning speed on rather large objects).
There's a library for that: jsonpath
This question was asked two years ago before jsonQ. jsonQ allows us to write code to find siblings, traverse trees etc. without having to write a bunch of loops inside loops. While the question wanted a way to find it in native JS, I think my 2-year-old question is a bit naive now. I was really looking for a library like jsonQ to avoid writing a bunch of ugly loops (though I could do the work myself).
I was searching and just found this: https://github.com/lloyd/JSONSelect. I haven't tried it yet but it seems to be a good choice.
The question is old, but may this answer can help someone.
To select an item from list, you can use Javascript filter function:
var data = { "objects":[
{"foo":"x","bar":"a"},
{"foo":"y","bar":"b"}
]}
var someobject = filterObject('x');
function filterObject(fooValue) {
return data.objects.filter(function(item) {
return item.foo == fooValue;
}
}
Related
I'm going through a porting exercise going from JavaScript to TypeScript and have hit the following issue.
In the original JavaScript code I've got:
var children = someJQueryElement.children('div');
var sortedChildren = children.sort(someSortFunction);
In TypeScript (1.4) all the jQuery methods return JQuery which isn't an array and therefore can't have sort called on it.
How should I go about solving this?
As an idea, have you tried to tell TypeScript to treat it as an array using casting?
var children = someJQueryElement.children('div');
var sortedChildren = (<Array>children).sort(someSortFunction);
This seems like a fairly tedious solution, though, if you have to do this in many places. Hopefully someone has a better answer.
You can change to a normal array using .get()
children.get().sort(someSortFunction);
You can use Array.slice.apply to pass in the array-like object and convert it to a proper array.
var children = [].slice.apply(someJQueryElement.children('div'));
This is also a useful practice if you're not using jQuery but want to convert any other array-like objects, like arguments, for example.
says I've this :
var user = [{'id':1,'gender':'male'},{'id':2,'gender':'female'}]
I want to use push() to insert
'owner':true
into the first array so that it become like this
var user = [{'id':1,'gender':'male','owner':true},{'id':2,'gender':'female'}]
I tried
user[0].push({'owner':true});
but it doesn't work tht way.
#Kim Gysen gave you a solution that works. I think you're getting the logic between Arrays and Objects confused I just wanted to give you a solution using only JavaScript that may help you understand just what's going on here. Using libraries like jQuery are a great way to save time but for you I think it would be helpful to have a more comprehensive understanding.
user[0]['owner'] = true;
In the code above you are accessing your array by the 0th index which in this case is "'id':1" and adding a new property to it using Bracket Notation. Another way to do this would be using Dot Notation:
user[0].owner = true;
Think about the process of adding a property to an object:
var myObj = {};
myObj['newKey'] = "I'm a new value";
myObj['newKey2'] = "I'm an even newer value!";
The reason I gave you an answer is it may seem convenient to use jQuery but understanding JavaScript principles and syntax will help you out in the long run. Some good resources for you I'd suggest are CodeSchool and CodeAcademy
You are not pushing an object into an array, you are pushing an object into an object.
You can do this by using jquery's extend method.
var object = $.extend({}, object1, object2);
I come from a C# background. I've been working a lot with JavaScript lately. On a new app, I have a mysql/php back end. I'm going to be passing a lot of "types" back and forth.
So in my data base, I have several tables like
table1
id, fieldx,fieldy,fieldz
table2
id, fielda,fieldb,fielc
In c# I would definitely write classes for all those in the code. Which led me to implement things like so (in my JavaScript app):
function table1(id, x,y,z){
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
After about 6 tables worth of that, it suddenly occurred to me that maybe there was no point at all in making these classes.
So my question is, in a JavaScript app, do I use "classes" for data types? or should I just "document" which fields/types are expected and so in the code instead of
a.push(new table1(5,1,2,3));
I would just have
a.push({id:5,x:1,y:2,z:3});
This may seem like a preferences question but it's a fundamental language question that I have as I try to understand how to model my app's data in JavaScript. Is there any advantage of the classes (with only data fields) or is it just a mistake. Thanks.
It depends,
Note: Most of the programmers coming from a strong OO language will have trouble like you in regard to JavaScript's functional behavior (you are not alone).
If you want to create something closer to C# I would do the following:
function Table1(id, x, y, z) {
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
Table1.prototype.mySpecialTable1Method= function()
{
console.log(this.id);
};
Implementation:
var t = new Table1(1, 2, 3, 4);
t.mySpecialTable1Method();// outputs: 1
If you need to have methods that interact with the (soon to be) objects then I would definitely go with the code above. In addition it will make it clear when working with the objects that are related to a specific 'type' (naming the data).
But if your objects do not require any special "treatment" then I don't see any problem to use normal js object literals and pass them along (probably good for small projects).
Something along the lines:
var table1 = {};
table1.id = 1;
table1.x = 2;
table1.y = 3;
table1.z = 4;
console.log(table1.id); //outputs: 1
Extra reference:
http://www.youtube.com/watch?v=PMfcsYzj-9M
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
Update:
For the sake of readability and scalability and the point that you are coming from C# you may want to stick to the "class" implementation just because it will define the correlation between the raw data and the objects you are working with.
There is a good chance that you are going to work with some data that will probably be messy and unorganized.
MVC may be the solution for you. It tries to bring some order to the chaos that you are expecting. I recommend to check out some of them like: AngularJS or Ember.
Another solution may be reactive js - but mostly if you are going to interact with the DOM according to your data (ReactJS, and Facebook's React as some good ones).
As a note for security, I would like to add that mapping the data closely to the db isn't a best practice but its your call.
Javascript is a funny language, and there are plenty of ways to do things. An Object is an Object in Javascript with or without a name. {} is just a short-hand way to create one.
If you are going for readability, then your initial example would be the way to go.
If you just want to get the block of data into an array, then your second example is appropriate. Personally, I would use your later example if it is just data.
If you are using functions and what not as well as data storage, and plan on reusing it several times in your code, then yes, define your object and call it appropriately.
JavaScript has no classes, it is a functional language and a function is a first class citizen in js meaning that a function is an object.
From your example I can see that your intention for classes is simply to pass data and using json is perfect for this.
This question already has answers here:
What are the Alternatives to eval in JavaScript?
(11 answers)
Closed 7 years ago.
I work mainly with javascript, Jquery, knockout, etc
The thing that attracted eval() to me is
var a = 5;
var b = 10;
eval("a+b");
//Gives me output 15
Note: I work in cases where the value of a and b changes dynamically
In my work I'm dealing with a lot of dynamic objects from json, knockout, etc. So eval solves most of my problems.
But as I read I found there are so many issues with eval() like slowing down etc.
I searched a lot and haven't found any substitute for eval() when i have to evaluate equation obtaining as string into equation as object.
Can anyone suggest a plugin or function alternative to eval() keeping in mind the example i have given above
Problem:
I'm creating a Table from Json data using knockout mapping. So that what ever the format of json is the table is generated. I also calculate some field using knockout computed.
Right now I use hard-coded
self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })
self.salaryEqn(salEqnTxt);
I want to execute these equations dynamic. I can create it dynamicaly as string but to eval them is the issue I'm facing.
I want solution for
Is there a way to calculate a formula stored in a string in JavaScript without using eval?
Like a formula
"self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })"
Javascript is a very flexible language in this regard. There are very very few cases where eval() is the right answer to any given question, and it certainly isn't necessary here.
If your a and b variables are part of an object, you can access them with string subscripts:
ie myobj.a could also be referenced as myobj['a'].
From that, you can use a variable for the subscript, and thus you can reference any element in myobj dynamically -- ie:
var myobj = {a : 5, b : 10};
var dynamicProperty1 = 'a';
var dynamicProperty2 = 'b';
//gives 15.
alert( myobj[dynamicProperty1] + myobj[dynamicProperty2] );
No eval() required. You can build the dynamicProperty strings however you wish, so there's virtually infinite flexibility.
If your a and b variables are globals, JS globals in the browser are actually children of the window object, so you can still use this technique even with globals.
ie your global variable a could also be accessed via window.a or window['a'], with the latter option allowing you to do the same dynamicProperty trick described above.
Hope that helps.
do you mean that you want to calculate an equation that you can't know until you've received it?
if so see Calculate string value in javascript, not using eval .
in short:
eval CAN be used sometimes, but only if the equation string comes from a trusted source, and there you need something like evaluating dynamic equations.
maybe using window['var' + num] might be more useful for you. i don't quite understand your question sorry.
If you can collect them under an object like root = {a: 1, b: 2}, then
Object.observe(root, function(newValues) {
res = newValues.object.a + newValues.object.b;
});
can keep your res variable up to date whenever the a or b changes
It looks like you are trying to do dynamic equations created by a user.
For example it could be 'a+b+c' or 'dog+cat', and you don't know.
The best way to handle user-input equations like that is to parse the text into tokens and then translate the tokens into values/operands.
That's a lot of work, but there are pre-rolled solutions. For example, math.js
Check more alternatives to eval in this question and another one here which both might be considered a duplicate...
I understand this is a link only answer, but it will for sure be helpful to others searching for alteratives to eval.
I want to pull a tree structured set of objects from a web service represented with JSON
When I unpack that, I'll wind up with a structure which uses vanilla Javascript objects. What I'd like to be able to do is bind each node to a specific class, so that method calls become available on each node of the tree.
My solution, using jQuery .extend()
Here's a simplified example which illustrates the approach.
I might define a simple class using jQuery .extend() as follows...
MyNode= function() {
this.init();
}
$.extend(MyNode.prototype, {
init: function() {
// do initialization here
},
getName: function() {
return this.nodeName;
}
});
Now given a simple object like this
var tree={
nodeName:'frumious',
nodeType:'MyNode'
}
I can make the object appear to be an instance of the desired nodeType with
$.extend(tree, eval(tree.nodeType+'.prototype'));
Note that I want the object to declare the class name, so I've used eval to locate the appropriate prototype for that class. (Thanks to Rob W for suggesting window[tree.nodeType].prototype as a better alternative)
Now I can do things like alert(tree.getName());
Better ways?
I write StackOverflow questions and find the act of describing it in enough detail to avoid a downvote is enough for me to solve it myself. This was no exception, but I'd be interested to hear of any more elegant approaches to this problem. This solution gets the job done, but I can't help but feel there must be other approaches...
I'd get rid off eval, and use:
$.extend(tree, window[tree.nodeType].prototype);
If MyNode is a local, but known variable, add it to an object, for reference. Eg:
var collection = {};
collection['MyNode'] = MyNode;
$.extend(tree, collection[tree.nodeType].prototype);
Alternatively, if the structure of the JSON is solid, I recommend a custom JSON parser, which also allows you to validate properties prior addition.