Obtaining value via $ref / self reference - javascript

I'd like to to use a reference to refer to an existing object within my JSON structure; specifically access it's keys and values.
I thought it reasonable that I should be able to refer to an existing object and then use dot notation to access said keys and values - but more likely I'm misunderstanding the technology.
var courses = {
Engl101 : {
course : "English 101",
units : 5,
req_type : false ,
req: false
},
Engl112: {
course : "English 112",
units : 3,
req_type : "prerequisite" ,
req: { "$ref": "#/courses/Engl101"}
}
}
I expected I should be able to then access my prerequisite course with
courses.Engl112.req
What I actually get appears to be a string with no access to child keys/values.
Also, I tried to access via Object.keys(courses.Engl112.req) with variations of [0] numerated indices with no real progress.
Is this feasible and thank you in advance?

If your courses are unique by name you could put
req: "English101"
You could then access the required courses by
courses[courses.Engl112.req]

With pure JavaScript, you cannot do such a thing.
But some libraries exist to support internal and external references in JSON. A famous one: json-schema-ref-parser.

Related

object identifications in javascript and restful service

Consider classes
Product = {
variations: [],
properties: []
}
Property = {
values: []
}
Variation = {
values: []
}
Value = {
simpleString:""
}
On the client (in JS) I first create products with properties and the possible values each property may have.
After that I create variations. Each of them can have a set of several values. But it only can "use" the values, which do already exist for properties.
In the next step, I move that product-object over to rest api.
While in JS the values used in a variation points to the original object in the product property, after encoding to JSON and backwarts to stdClass in PHP behind the restful service, this link gets lost.
Of course I could give them IDs on my own and call them temp_id or so. Hacky.
How would pros do it?
PHP
I simply deserialize the incomming JSON $object = json_decode($json); and use RedBeans and Piped to manage that end. What it does is mainly just moving through the properties and create objects with ..._id == null (then they get a unique ID).
Let's say I would do it manually:
I'd walk through the properties and store each value-object into the MySQL-db. Say
{
value_id: null,
simpleString: 'Green'
}
After storing it will have the value_id = 111.
Now I walk through the variations. One of these uses the Green-Value. But since this value will also be
{
value_id: null,
simpleString: 'Green'
}
how could I identify them? The string, of course, is too weak - no one could consider that. As mentioned above, I could give them temporary IDs. But surely there is a better way.

Retrieving JS' Object value without knowing it's name

This is a fairly common question here in SO, and I've looked into quite a few of them before deciding to ask this question.
I have a function, hereby called CheckObjectConsistency which receives a single parameter, an object of the following syntax:
objEntry:
{
objCheck: anotherObject,
properties: [
{
//PropertyValue: (integer,string,double,whatever), //this won't work.
PropertyName: string,
ifDefined: function,
ifUndefined: function
}
,...
]
}
What this function does is... considering the given parameter is correctly designed, it gets the objCheck contained within it (var chk = objEntry.objCheck;), It then procedes to check if it contains the properties contained in this collection.
Like this
for(x=0;x<=properties.length;x++){
if(objCheck.hasOwnProperty(properties[x].PropertyName)){
properties[x].ifDefined();
}
else{
properties[x].ifUndefined();
}
What I want is... I want to bring it to yet another level of dynamicity: Given the propositions that IfDefined and IfUndefined are functions to be called, respectively, if the currently-pointed PropertyName exists, and otherwise, I want to call these functions while providing them, as parameters, the very objCheck.PropertyName's value, so that it can be treated before returning to the user.
I'll give a usage example:
I will feed this function an object I received from an external provider (say, a foreign JSON-returning-WebService) from which I know a few properties that may or may not be defined.
For example, this object can be either:
var userData1 = {
userID : 1
userName: "JoffreyBaratheon",
cargo: "King",
age: 12,
motherID : 2,
//fatherID: 5,--Not defined
Status: Alive
}
or
var userData2 = {
userID :
userName: "Gendry",
cargo: "Forger Apprentice",
//age: 35, -- Not Defined
//motherID: 4,-- Not Defined
fatherID: 3,
Status: Alive
}
My function will receive:
var objEntry=
{
objCheck: userData1,
properties: [
{
PropertyName: "age",
ifDefined: function(val){alert("He/she has an age defined, it's "+val+" !");},
ifUndefined: function(){alert("He/she does not have an age defined, so we're assuming 20.");},
},
{
PropertyName: "fatherID",
ifDefined: function(val){alert("He/she has a known father, his ID is "+val+" !");},
ifUndefined: function(){alert("Oh, phooey, we don't (blink!blink!) know who his father is!");},
}
]
}
CheckObjectConsistency(objEntry); // Will alert twice, saying that Joffrey's age is 12, and that his father is supposedly unknown.
ifDefined will only actually work if, instead of properties[x].ifDefined();, I somehow provide it with properties[x].ifDefined(PropertyValue);. And here, at last, lies my question.
Being inside the consistency-checking-function, I only know a given property's name if it's provided. Being inside it, I can't simply call it's value, since there is no such function as properties[x].ifUndefined(properties[x].GetValueFromProperty(properties[x].PropertyName)) ,... is there?
I'm sorry. Not being a native english speaker (I'm brazilian), I can't properly express my doubts in a short way, so I prefer to take my time writing a long text, in an (hopefully not wasted) attempt to make it clearer.
If, even so, my doubt is unclear, please let me know.
I think you're looking for the bracket notation here. It allows you to provide an arbitrary value as key to access the object. Also, you know its name. You have your properties object right?
objEntry.properties.forEach(function(property){
// Check if objCheck has a property with name given by PropertyName
if(!objEntry.objCheck.hasOwnProperty(property.PropertyName)){
// If it doesn't, call isUndefined
property.isUndefined();
} else {
// If it does, call isDefined and passing it the value
// Note the bracket notation, allowing us to provide an arbitrary key
// provided by a variable value to access objCheck which in this case is
// the value of PropertyName
property.isDefined(objEntry.objCheck[property.PropertyName]);
}
});
Oh yeah, forEach is a method of arrays which allows you to loop over them. You can still do the same with regular loops though.

Hash of hash of list of lists in javascript

I'm a perl programmer learning javascript. In perl, I would frequently use hashes to create 'data structures' from data returned from a database query. For example, I would build hashes like this:
*loop through list of data*
push(#{$hash{$key1}{$key2}}, [$value1, $value2, $value3, $value4]);
*endloop*
this would add a reference to the list of four values to a list in the hash (with multiple keys).
I'm having a hard time finding information on how I would implement a similar structure in javascript. My goal is to read in a JSON file that has a list of objects (which has no particular order) and turn it into a hash so it can be sorted by the keys and then display it in an HTML table.
Perhaps this is the wrong way to think about this problem and javascript will have a different approach. I'd like to know if what I'm trying to do is possible, the code to create the hash, and the code to access the hash.
Thanks,
Rob
This is my straight translation, tested at the Google Chrome console prompt >
> hash = {}
Object {}
> hash["key1"] = {}
Object {}
> hash["key1"]["key2"] = []
[]
> hash["key1"]["key2"].push([ 'value1', 'value2', 'value3', 'value4'])
1
> hash
Object {key1: Object}
> JSON.stringify(hash, null, 2)
"{
"key1": {
"key2": [
[
"value1",
"value2",
"value3",
"value4"
]
]
}
}"
Hash in Perl is just set of key/value pairs. Javascript has similar data structure - Objects. You could do what you want
> a = {}
{}
> a.res = []
[]
> a.res.push([1,2,3])
1
> a.res.push([3,"sd",1])
2
> a
{ res:
[ [ 1, 2, 3 ],
[ 3, 'sd', 1 ] ] }
Javascript does not have an ordered hash and a lookup with multiple keys. You can use the properties of an object to create a lookup by a single unique key and you can then build on that notion as needed. See this answer for an idea how to implement a simple form of hash or set in javascript.
The basic idea is that you create an object and then add key/value pairs to it:
var myLookup = {};
myLookup[key1] = value1;
myLookup[key2] = value2;
Then, you can look up a value by the key:
console.log(myLookup[key1]); // shows value1
If you want more specific help, you will have to be more specific in your question. Show us what the JSON you start with and describe exactly how you want to be able to access it so we can figure out what type of JS data structure makes the most sense to put it in. Remember, once the JSON is parsed, it is already in a javascript data structure at that point so the it becomes a question of what kind of access you need to make to the data to understand whether the data should be restructured with certain key lookups?
It is generally best to concentrate on problem/solution and NOT on trying to do something the same way another language does it.

Javascript properties reflection

First of all, let me warn you that i am not a javascript guru.
I already found a few questions regarding this topic but almost all of them answer with the same solution.
I have a simple custom javascript object:
var errorMsg ={
msg1 : "x",
msg2 : "y",
msg3 : "z",
msg4 : "t"
}
and i want to get all the properties names from the object like ["msg1","msg2","msg3","msg4"].
Like i told almost solution point to the use of the for/in loop to iterate over all properties name. But my app will run in IE6 and above, and i research that IE does not support this loop or at least the IE6. So what can i do ?
The last question is , where can i find a good javascript reference ? I saw that the Object have a method that returns keys like Object.keys() , where can i find a good reference that gives me all the properties and method related with javascript built in objects ?
You could define a generic method for returning an array of keys from any object,
and use the function's call method to operate on the errorMsg object:
var errorMsg={
msg1:"x",
msg2:"y",
msg3:"z",
msg4:"t"
}
function keyArray(){
var A= [];
for(var p in this){
if(this.hasOwnProperty(p)) A.push(p);
}
return A;
}
keyArray.call(errorMsg)
/* returned value: (Array)
msg1,msg2,msg3,msg4
*/
First, see Does Javascript have an enhanced for loop syntax similar to Java's where we were just discussing this. But since you are using an object instead of an Array here, not all of the answers will apply. Here you will want to be sure that you're using a solution that involves hasOwnProperty.
In terms of a reference, I always use https://developer.mozilla.org/en/JavaScript/Reference. Everything that is listed there is of very high quality. Just beware that not everything listed will apply equally to all browsers.
If for-in is no option, you could use an array containing message objects. You can use a standard for loop this way.
var errorMsg = [
{ name : "msg1", value : "x" },
{ name : "msg2", value : "y" },
{ name : "msg3", value : "z" },
{ name : "msg4", value : "t" }
];
You can't access the messages by name any more though - mapping message name to an index in errorMsg might be a workaround for this.

Why can't I access JSON objects by key in JavaScript?

This is my JSON object:
{ text: 'stuff',
user: 'user1
}
when I run a typeof jsonObj, I get object. When I run an jsonOb.length, I get undefined. When I tried to access the text property via console.log(jsonObj.text), I get undefined.
So how can I properly access everything in JavaScript?
I don't want to use jQuery as this is all node.js programming so it's serverside.
UPDATED - full JSON
{ text: '#junk_666 おかえりか',
user:
{ display_name: 'mono',
screen_name: 'monochrm',
klout_score: null,
location_str: '画面の前',
utc_offset: '32400' },
venue_id: 1304409836517,
match_type: 'twitter',
tweet_id: '116494264137023489',
created_at_unix: 1316609371,
meta:
{ matchedPhrase: 'junk',
venueName: 'deletemepls really long name' },
tags: [ '' ],
indexed_at_unix: 1316609416 }
The json seems to be invalid
{
"text": "stuff",
"user": "user1"
}
I copied and pasted your object into a FireBug console and it recognized it.
If you need to count the number of key/value pairs, you can use a function such as this one to do it:
function numMembers(o) {
var i=0;
for (a in o) {
i++;
}
return i;
}
You should be able to access the value of the text property via jsonObj.text. Are you sure that your object is being referenced by jsonObj? Also, can you access the values for simpler objects such as the ones mentioned in other posts if you create them? Furthermore, does anything work if you use only ASCII characters? For some reason, it might not be handling some of the non-Latin characters properly.
First, what you have is not JSON because JSON requires property name to be in double quotes. It is a valid JavaScript object literal though, so I'll assume that's how you're using it.
Secondly, JavaScript objects in general do not have a length property. Arrays do.
There's no problem with your object literal so there must be some other problem elsewhere in your code.
Try this:
{ text: 'stuff',
user: 'user1'
}
You left off an apostrophe.
Now that you've posted your full JS code (that's not JSON, as #josnidhin points out)... works fine in jsFiddle. http://jsfiddle.net/Rs9R4/ I don't believe a JS Object has .length, just Arrays.

Categories

Resources