I have built an "enumeration" in javascript using the following syntax:
MyEnum = {
MY_VAL_1 : { name: "Value 1" },
MY_VAL_2 : { name: "Value 2" },
MY_VAL_3 : { name: "Value 3" }
};
I want to store a dictionary containing 0 or more of these enumeration values and I want to be able to test for the existence of any particular value in the dictionary. I also want to show the values that are not in the dictionary inside a dropdown, and the values that are in the dictionary in another dropdown, and have buttons that allow the user to add or remove values to or from the dictionary using these dropdowns.
I can get the dropdowns working, but I can't test for existence in the dictionary outside of a "for (x in MyEnum)" block. If I use:
list[MyEnum.MY_VAL_1]
I always get false (I guess because the items are stored without the MyEnum namespace?). If I try:
list[MY_VAL_1]
I just get an Uncaught ReferenceError.
How can I get this to work, or is there a better way to do this?
Here is a jsFiddle of what I've done so far: http://jsfiddle.net/jKfbh/3/
MyEnum.MY_VAL_1 returns the object you specified, { name: "Value 1" }.
To test if a value is in your "list" (which, in fact, is an object or dictionary), you should use this code:
if (list["MY_VAL_1"]) {
alert('val 1 is in list');
}
var MyEnum = {
MY_VAL_1 : { name: "Value 1" },
MY_VAL_2 : { name: "Value 2" },
MY_VAL_3 : { name: "Value 3" }
};
alert("MY_VAL_1" in MyEnum);
JavaScript doesn't have enums. In ES5 you could define properties as sealed frozen etc. which would make them perform similarly to enums, but, in all honesty, if you found yourself in need of such a feature in JavaScript, you probably need to reconsider your design. This doesn't mean that your design is necessarily bad, it's that JavaScript provides almost no instrumentation to do what you want.
you can check the value like this:
if(MyEnum['MY_VAL_1']){
alert('val 1 in the list');
}
Related
So I need to edit a property of an object in javascript. It contains multiple of the same object name. I am fairly familiar with javascript. My object looks like this:
var object = {
Sub: {
name: "FirstSubName",
propertyToChange: "Keep me the same"
},
Sub: {
name: "SecondSubName",
propertyToChange: "Change me" //This is the property I need to change
}
}
I want to change the second property of the second "Sub" to "ChangedProperty". If I want to do it without using chronological order (like object.Sub[1].propertyToChange = "ChangedProperty", what would I do?
As Bergi said, you cannot have these two properties. What you can have is an array, like this:
var object = {
Sub:[{name: "X", prop: "a property"},{name: "Y", prop: "another prop"}]
}
So, you can access them with the array notation you used in your question or either using a forEach for comparing values, for instance.
Hope this helps.
Given an javascript object:
myList = {
"1": "Winter",
"2": "Spring",
"3": "Summer",
"4": "Fall"
}
and supposing that the variable season contains the first item, how do I access "1" and/or "Winter"?
Edit: myList['1'] is not the answer I am looking for because I want to access either "1" or "Winter" from the season variable. It is not a duplicate of the marked question.
Instead, I want to do something like:
for(var season in myList) {
foo( season.key ); // should be "1" on the first pass
bar( sesson.val ); // should be "Winter" on the first pass
}
I've seen somewhere that you can do an inner loop to get the key and value. Is there some other way aside from doing that?
Libraries like lodash and underscore were made to help with these kinds of problems. You can use the lodash#forEach function to iterate over the values (and keys if applicable) in a collection (array or object).
Check out: https://lodash.com/docs#forEach
So with your example you could do something like:
_.forEach(myList, function(value, key) {
foo(key); // 1
bar(value); // "Winter"
});
You can simply get the value of the key by:
myList['1']
To get the key from the value there is no standard method available in javascript. You would have to write your own method for this.
I am new to Knockout, and I have the following question:
I have Ids coming from database and each Id has its corresponding Description (this is actualy enum in .NET, but I do not think this is important in this question).
For example,
a) for variable "PType": 0 - Undefined; 1 - Low Structure; 2 - Hight Structure
b) for variable "ClientType": 0 - Undefined, 1 - P Type; 2 - S Type
etc. for some other variables also
How to properly define model for this dependency?
Currently I have only Ids like
PType: ko.observable();
ClientType: ko.observable();
and I show Ids on page:
<span data-bind="text: PType"></span>
<span data-bind="text: ClientType"></span>
However, I need to have something like: PTypeDescription and ClientTypeDescription to show for User. I believe that those are somehow dependant variables, but cannot get it working.
First i 'll suppose that you already know what enums you have and when you get data via AJAX, you get enums value represented as integer not string
You can simulate enums in Javascript easily (check this article):
var PType = { 0: "Undefined", 1: "Low Structure", 2: "Hight Structure" }
var ClientType = { 0: "Undefined", 1: "P Type", 2: "S Type" }
So, your view-model can be something like:
var itemObj = {
PType: ko.observable(0);
ClientType: ko.observable(0);
property1:ko.observable('')// put here the other properties if you have more
}
To get your enum represnted as enum you write call function that takes the value("your enum key") and which enum to use("you can use inline function for that").
JsFiddle Demo
Update
Check this SO answer to another implementaion for Enums in JS, it's simple and effective
Given a data structure that contains an array of JavaScript objects, how can I bind a certain entry from that array to an input field using Angular?
The data structure looks like this:
$scope.data = {
name: 'Foo Bar',
fields: [
{field: "F1", value: "1F"},
{field: "F2", value: "2F"},
{field: "F3", value: "3F"}
]
};
The fields array contains several instances of the given structure, with each entry having both a field attribute and a value attribute.
How can I bind an input control to the value field attribute of the array entry with the field F1?
<input ng-model="???"/>
I know that I could bind all fields using an ng-repeat, but that's not what I want. The above data is just an example from a much larger list of fields, where I only want to bind a pre-defined subset of fields to controls on the screen. The subset is not based on the attributes in the array entries, but is known at design time of the page.
So for the above example, I would try to bind F1 to one input on the page, and F2 to another one. F3 would not be bound to a control.
I've seen examples where a function was used in the ng-model, but it doesn't seem to work with Angular 1.1.0.
Is there another clever way to bind the input field to a specific array entry?
Here's a fiddle that has an example, but does not work since it's trying to use function in the ng-model attribute: http://jsfiddle.net/nwinkler/cbnAU/4/
Update
Based on the recommendation below, this is what it should look like: http://jsfiddle.net/nwinkler/cbnAU/7/
I personally would reorganize the array in a way that field property of an entry of the array become the identifier of the object. Mhhh that sentence may sound strange. What I mean is the following:
$scope.data = {
name: 'F1',
fields: {
F1: {
value: "1F"
},
F2: {
value: "2F"
}
}
};
If you want to bind a the value dynamically and it's an easy and quick way to achieve it.
Here is your fiddle modified so that it words. http://jsfiddle.net/RZFm6/
I hope that helps
You can use an array of objects, just not an array of strings.
HTML:
<div ng-repeat="field in data.fields">
<input ng-model="field.val"/>
</div>
JS:
$scope.data = {
name: 'F1',
fields: [
{ val: "v1" },
{ val: "v2" }
]
};
I've updated #Flek's fiddle here: http://jsfiddle.net/RZFm6/6/
Edit: Sorry just read your question properly, you can still use an array with:
<label>Bound to F1:</label>
<input ng-model="data.fields[0].value"/>
though maybe stop and think. Is there going to be variable number of fields ? or are you making a predetermined number of fields ? Use an array in the former and an object for the latter.
One way to do it is to simply add the necessary references to the scope, like this:
$scope.fieldF1 = fieldValue('F1');
$scope.fieldF2 = fieldValue('F2');
And then use those references:
<input ng-model="fieldF1.value"/>
<input ng-model="fieldF2.value"/>
Fiddle: http://jsfiddle.net/cbnAU/5/
Note: I'm assuming that $scope.data is static, but if it happens to be dynamic you can always watch for changes on it and recalculate the references...
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.