How to declare nested objects in JavaScript? - javascript

I'm trying to create an object that contains an object, so think of it as a dictionary:
var dictionaries = {};
dictionaries.english_to_french =
{
{english:"hello",french:"bonjour"},
{english:"i want",french:"je veux"},
{english:"bla",french:"le bla"}
};
but it gives the error Uncaught SyntaxError: Unexpected token {
what am I doing wrong?
Thanks !
Edit
I'm sorry that I did not clarify what I want to do.
Edited the code above.

You're trying to give your object a property, and that property will be a single object:
dictionaries.english_to_french =
{english:"hello",french:"bonjour"}
;
You don't need the extra { }. You could declare the whole thing at once:
var dictionaries = {
english_to_french: {
english: "hello", french: "bonjour"
}
};
I would suggest that a better format for your dictionaries might be:
var dictionaries = {
english_to_french: {
"hello": "bonjour",
"chicken": "poulet", // ? something like that
"Englishman": "rosbif"
}
};
That way you can look up words directly without having to search. You could then create the reverse dictionary from that:
dictionaries.french_to_english = function(dict) {
var rv = {};
for (var eword in dict)
rv[dict[eword]] = eword;
return rv;
}(dictionaries.english_to_french);

In order to nest two or more objects, the objects need to have an attribute assigned to them. For example,
{
"hello":{
"english":"hello",
"french":"bonjour",
"portuguese":"ola"
},
"good day":{...},
"how are you":{...}
}
"hello" at the beginning of the object would be the attribute. Then the object is its value. So that way you can access the object by accessing its attribute. Just putting an object in an object does not work. That's why you're getting your error.

Related

Passing a param to build a JSON object

How can I pass the subCategory in as an parameter for the function? I have a working solution just passing in the param and then having a switch do the work to make the JSON.subcategory read from the right place. However I feel like there is some thing I am missing on making this more functional, or OO friendly.
So is there a way to make the passed param understand its a variable and not the object literal.
json = {
weather: ["rain", "snow","sun"],
news: ["events", "local","world"]
}
messageBuilder(weather)
function messageBuilder(passedVariable){
var object = json.passedVariable;
// object = json.weather
console.log(JSON.stringify(object));
}
Also am I using the terms correctly? I tried to search google for an answer and ended up not really finding anything.
Just pass the object property key name (sub category) in as a string and use bracket notation to pick it from the data in the function.
Note: that's an object, not JSON, so I've named it as such in the example.
const obj = {
weather: ["rain", "snow", "sun"],
news: ["events", "local", "world"]
};
messageBuilder('weather');
function messageBuilder(subCat){
var object = obj[subCat];
console.log(JSON.stringify(object));
}
Just modify your code a little bit:
json = {
weather : [
"rain", "snow","sun"
],
news : [
"events", "local","world"
]
}
messageBuilder('weather');
function messageBuilder(passedVariable){
var object = json[passedVariable];
// object = json.weather
console.log(object);
}
First of all you should pass your parameter as a string. Then just pull out the property from the object using object['property']

Replace String In Object Property Value After Looping Array Javascript

I'm needing to replace a character in an object's property value. I'm looping over the array of objects (outputting to console) and retrieving the FeatureUrl property.
I have data coming back from the Svc for that property in the following form:
index.html#/blah
I'm needing to replace the '#' with '#/app' so that my new url comes back in the following form:
index.html#/app/blah
I'm not sure if .replace is the right method to use here, but it is what I have seen suggested. Can someone point me in the right direction?
var localFeatureDetails = function() {
$scope.user = userService.GetUserInformation();
$scope.featureDetails = $scope.user.Features;
var featureUrlRewrite = function () {
var index;
var urlCount;
for (index = 0; index < $scope.featureDetails.length; index++) {
urlCount = $scope.featureDetails[index];
urlCount.FeatureUrl.replace("#","#/app");
console.log(urlCount);
}
};
featureUrlRewrite();
};
localFeatureDetails();
I did not test your code but based on how .replace() works you have to assign the value to your object property again by overriding it otherwise you're not saving the value.
Assuming everything else is correct, try this:
$scope.featureDetails[index].FeatureUrl = urlCount.FeatureUrl.replace("#","#/app");
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
I think that you might want something more like this
$scope.featureDetails.map(detail => angular.merge({}, detail,
{ FeatureUrl: detail.replace('#', '#/app') }))
instead of the bulky for loop.
we take every detail object out of the featureDetails array, access the FeatureUrl property and replace the # with #/app
.merge(destination, ...sources) merges sources into destination, left-to-right, overwriting properties as it goes.
so angular.merge({}, {foo: 5, bar: 3}, {foo: 7}) would return { foo: 7, bar: 3 }
Removed the console.log() but you can always
console.log($scope.featureDetails);
and then look at the object that is returned in the inspector.

Ensure object properties passed through function equal certain values?

I have a class which uses certain properties throughout methods.
function MyClass(elementSelectors) {
this.elements = {};
for (var elementSelector in elementSelectors) {
this.elements[elementSelector] = document.querySelector(elementSelector);
}
}
myClass.prototype.usesAnElement = function () {
console.log(this.elements['header']);
};
var elementSelectors = {
headr: '[class="header"]' // this is sort of an error?
}
var myClass = new MyClass();
Now I'm thinking of future errors. What if someone accidentally misspells a property. I'm wondering if there was a secret way of requiring only certain properties (other than checking them in a separate array containing the possibilities).
You can test the property against a map of available ones and only attempt to use it if it's valid
//available properties
avail = {
"header": true, //or anything that evaluates to true
"foo": true,
"bar": true
}
//test if a property is valid before trying to do something with it
if (Object.prototype.hasOwnProperty.call(avail, elementSelector)) {
this.elements[elementSelector] = document.querySelector(elementSelectors[elementSelector]);
}
Edit
Or, if you don't care for IE8 support, or don't mind adding a polyfill for indexOf you can use arrays (solution suggested below).

How do you access an object within an object from an argument in Javascript? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Accessing nested JavaScript objects with string key
I have the function
function _get(name) {
return plugin._optionsObj[name] !== undefined ?
plugin._optionsObj[name] : plugin._defaults[name];
}
I would like to be able to have objects inside of my _defaults object, but then I don't know how to retrieve them but using just one set of square brackets.
i.e.
plugin._defaults = {
val1: 1,
val2: 2,
obj1: {
someVal: 3
}
}
Is it possible to access 'someVal' from the function I have above? I tried passing 'obj1.someVal' for the argument and it didn't work. Ideas?
Edit: I have found a solution and I posted it below as an answer. I've written a very nice little function to do go through the nested values with a string and I didn't have to change my function much to implement it. I hope this helps anyone in a similar situation.
I suspect that you won't always have a one-level nested object to access, so the cleaner way to do this is to use a function that traverses an object based on a string path. Here's one that is coded as a mixin for Underscore. You can then just use it like so:
_.deep(plugin._defaults, 'obj1.someVal');
This thread also has some non-Underscore alternatives.
Pass multiple arguments, and iterate over the arguments object.
function _get(/* name1, name2, namen */) {
var item = plugin._optionsObj,
defItem = plugin._defaults;
for (var i = 0; i < arguments.length; i++) {
item = item[arguments[i]];
defItem = defItem[arguments[i]];
if (item == null || defItem == null)
break;
}
return item == null ? defItem : item;
}
var opt = _get("obj1", "someVal")
I found a solution for this problem, at least one that will accommodate myself, and I'd like to share it in case it can help someone else with this problem. My biggest difficulty is that I did not know the depth of the nested value so I wanted to find a solution that would work for deeply nested objects and without requiring to redesign anything.
/* Retrieve the nested object value by using a string.
The string should be formatted by separating the properties with a period.
#param obj object to pass to the function
propertyStr string containing properties separated by periods
#return nested object value. Note: may also return an object */
function _nestedObjVal(obj, propertyStr) {
var properties = propertyStr.split('.');
if (properties.length > 1) {
var otherProperties = propertyStr.slice(properties[0].length+1); //separate the other properties
return _nestedObjVal(obj[properties[0]], otherProperties); //continue until there are no more periods in the string
} else {
return obj[propertyStr];
}
}
function _get(name) {
if (name.indexOf('.') !== -1) {
//name contains nested object
var userDefined = _nestedObjVal(plugin._optionsObj, name);
return userDefined !== undefined ? userDefined : _nestedObjVal(plugin._defaults, name);
} else {
return plugin._optionsObj[name] !== undefined ?
plugin._optionsObj[name] : plugin._defaults[name];
}
}
To retrieve objects inside of your _defaults object you'll need to improve your _get function.
For example you may pass an array of strings (each string representing a propery name) to _get to allow access to deeply nested objects.

Get values from object if the name of the object is stored as a variable?

I have a JSON object return with the following format:
"miscObject": {
"205": [
{
"h": "Foo",
"l": "Bar"
}
]
}
miscObject contains somewhere over 1500 entries, each named incrementally.
How can I get to the values of 'miscObject.205.h' and 'miscObject.205.l' if I have "205" stored in variable without having to loop through all of the objects inside miscObject?
It seems that you're talking about Javascript objects rather than a JSON string.
x[y] and x.y are mostly interchangeable when accessing properties of Javascript objects, with the distinction that y in the former may be an expression.
Take advantage of this to solve your problem, like so:
var num = '205';
console.log(miscObject[num].l);
// ^^^^^
// \
// instead of `.num`, which wouldn't be the same as
// `num` is not the literal name of the property
Use the member lookup syntax
var miscObject = $.parseJSON(theJsonString);
var name = '205';
miscObject[name].h;
Object values can be accessed 2 ways--using the 'dot' notation as you mentioned, or by using []'s:
The following should work:
var result = miscObject["205"].h;
var miscObject = JSON.parse(your-JSON-object);
var value = miscObject['205'].h
You can do this to get the object:
num = '205'
miscObject[num]

Categories