I have below function in my dojo class:
dojo.declare("someclass", null, {
getSomeObject: function(id, name, description) {
console.log("id=", id, ", name=", name, ", description=", description);
var newObj = {
"id": id,
"name": name,
"description": description
};
console.log("newObj=", newObj);
return newObj;
}
});
This was fine until I upgraded the product I was working on. When I run the code now, somehow inside "newObj", all attribute values are turned into array - i.e. when "123" is passed as id value to function, inside newObj, "id" attribute value is ["123"].
I have tried using different ways to create object - with "new Object()", etc. Nothing seems to help. When I run the same code in the old product, it works as expected!!!
Here is an output from Google Chrome console --
id= 5962960 , name= sng2 , description= test
newObj=
Object
_RI: true
description: Array[1]
id: Array[1]
name: Array[1]
__proto__: Object
Any help???
I suppose you are using an ItemFileReadStore or ItemFileWriteStore.
Then it is absolutely normal, these stores works with arrays internally.
To get the value you should do as recommended in the doc:
store.getValue(storeItem, "property");
or if you're certain that value represented in propery, you can safely typecast by doing + ""
Related
I'm very new to javascript and have not had any formal education on it. I've looked at multiple sources and I can't seem to find a solution to my issue.
I am trying to create a button with a value equal to an object that is nested inside other objects. I will have a lot of other buttons on my site with the same function but should refer to different data sets.
When the button is clicked I would like the function to grab the value of the button (which should be an object) and declare a new variable equal to the object that has been passed.
I can print the data I want just fine to the log, but when I try to print the value of the variable that should now how the same data I keep getting [object Object]
(From there I will be populating a graph that will change every time a new button is clicked.)
example of my object
var Wall = {
"Option1": {},
"Option2": {},
"Option3": {
"Option1_3": {
"Option1_1_3": {
"Total Something": "100",
"Total Something Else": "20",
"Another Total": "40",
"More totals": "20",
"Total": "20",
},
"Option2_1_3": {},
"Option3_1_3": {}
},
"Option2_3": {},
},
"Option4": {},
"Option5": {}
};
creating the button and when clicked function
document.getElementById('Option1_3').innerHTML = (`<button class="button" value="${Wall.Option3.Option1_3}" onclick= "PopulateGraph(this.value)">Wall Time</button>`);
console.log(Wall.Option3.Option1_3);
function PopulateGraph(val){
console.log(val);
}
Output
This happens because when you use ${Wall.Option3.Option1_3} it is gonna have the same effect as Wall.Option3.Option1_3.toString() which is [object Object] (this is true for any objects as well as Arrays)
Your choices here are:
Either use {JSON.stringify(Wall.Option3.Option1_3)
Or if you don't wanna output plain JSON you can use Object.keys() or some other methods to break down the object before parsing it.
As #Andreas already mentioned, the content of any value attribute can only be a string. So one way of doing what you wanted would be to convert the objects into JSON-strings and convert them beack at the time of the button click:
var Wall ={
"Option1":{},
"Option2":{},
"Option3":{
"Option1_3":{
"Option1_1_3":{
"Total Something":"100",
"Total Something Else":"20",
"Another Total":"40",
"More totals":"20",
"Total":"20",
},
"Option2_1_3":{},
"Option3_1_3":{}
},
"Option2_3":{},
},
"Option4":{},
"Option5":{}};
document.getElementById('Option1_3').innerHTML = (`<button class="button" value='${JSON.stringify(Wall.Option3.Option1_3)}' onclick= "PopulateGraph(this.value)">Wall Time</button>`);
// console.log(Wall.Option3.Option1_3);
function PopulateGraph(val){
console.log(JSON.parse(val));
}
<div id="Option1_3"></div>
Alternatively you could not assign the actual object to the button but only the key to finding the object (as a string: "Wall.Option3.Option1_3"). The button click handler will then find the object on the basis of the passed key:
var Wall ={
"Option1":{},
"Option2":{},
"Option3":{
"Option1_3":{
"Option1_1_3":{
"Total Something":"100",
"Total Something Else":"20",
"Another Total":"40",
"More totals":"20",
"Total":"20",
},
"Option2_1_3":{},
"Option3_1_3":{}
},
"Option2_3":{},
},
"Option4":{},
"Option5":{}};
document.getElementById('Option1_3').innerHTML = (`<button class="button"
value="Wall.Option3.Option1_3" onclick= "PopulateGraph(this.value)">Wall Time</button>`);
function PopulateGraph(addr){
console.log(addr.split('.').reduce((a,c)=>a[c],window));
}
<div id="Option1_3"></div>
The expression addr.split('.').reduce((a,c)=>a[c],window) deserves some further explanation: The "address string" addris first split into its components: ['Wall','Option3','Option1_3'] and then the reduce() method is applied. The reduce callback function takes each value in turn and returns an underlying object of the passed a object. Initially a is set to the window object, where the Wall variable can be found as a property. The found sub-object is returned and will be used as a in the next reduce-iteration.
I'm using the following: Ionic 3, Angularfire 2, usb connected iphone & Safari Developer console for native cordova testing (for full context).
The goal is to run through the numbers retrieved from the phone contacts and see if they exist in any of the Firebase /users/~user id string~/ ..then later do things if they do.
The brief issue outline is that my approach is returning empty arrays for each number, as though the Angularfire equalTo query is not getting passed a value from the variable being fed into it.
Firebase structure
- users
- <user id string>
- name: "Some name"
- number: "1234 56789"
Exported JSON example (not real names or numbers):
"users" : {
"21JvDyuzNcbKTxGhCEyEzzSbwKc2" : {
"name" : "Gary Oose",
"number" : "1234 56789"
},
"F1AvstJCWqdzBWarXtxwcm01Ir02" : {
"name" : "Tina Urtle",
"number" : "987 654321"
},
"KNTJdnKaE3amJ79LOq40ztKWBWp2" : {
"name" : "Tommy Adpole",
"number" : "121 212 121"
}
}
The code is as follows..
contacts.find(["name", "phoneNumbers"], {multiple: true, hasPhoneNumber: true}).then(contacts => {
contacts.forEach((contact, index) => {
if (contacts[index].phoneNumbers !== null) {
var number_to_check = contacts[index].phoneNumbers[0].value;
//var number_to_check = contacts[index].phoneNumbers[0].value;toString();
//var number_to_check = "1234 56789";
console.log("contact_obj number = ", number_to_check);
let db_users_list = this.afDB.list(`/users/`,
{
query: {
orderByChild: 'number',
equalTo: number_to_check
}
}
).subscribe(number_matches => {
console.log('number_matches ', number_matches);
db_users_list.unsubscribe();
});
}
});
});
Running the above code
When either of the following lines are used:
var number_to_check = contacts[index].phoneNumbers[0].value;
or
var number_to_check = contacts[index].phoneNumbers[0].value.toString();
(the latter as I wasn't sure if the console output was lying to me that it was returning a string)
..the first console.log in the code confirms that a number has been returned from the native phone contacts, such as:
[Log] contact_obj number = - "1234 56789"
.. but the second console.log returns an empty array, as though nothing has matched against the Firebase DB in the query (.. it returns the same log for every number returned from the loop):
[Log] number_matches – [] (0)
The sanity check approach (..coffee's run out, I might be going mad)
When, instead of using either of the two lines above, I use the following line:
var number_to_check = "1234 56789";
(manually entering a static string value for the variable)
The first console.log returns the same number over and over, as expected seeing a static string value has been assigned to the number_to_check variable.
And the second console.log correctly returns an array for that number, indicating that the query has found a match for it in the Firebase DB, as seen below:
[Log] number_matches
Array (1)
0 {name: "Gary Oose", number: "1234 56789", $key: "21JvDyuzNcbKTxGhCEyEzzSbwKc2"}
So, does anyone have any pointers as to why the first approach (using the line of code below) is not working?
var number_to_check = contacts[index].phoneNumbers[0].value;
I get the feeling I'm missing something very obvious. Why would that changing variable not be getting picked up by the AngularFire equalTo query?
The issue is that there's sometimes whitespace in the string value the following line returns (from accessing the native phone's contact numbers):
contacts[index].phoneNumbers[0].value;
The solve is to remove the whitespace, like so:
contacts[index].phoneNumbers[0].value.replace(/\s/g, '');
Replace method found in a comment in Remove whitespaces inside a string in javascript
I imagine the whitespace being present in some but not all of the numbers must be down to how the phone stores the contact numbers when they are added in different ways.. i.e. via a shared contact, manual entry, etc).
With this solution in place I can successfully find the phone number matches (I also updated my Firebase number strings to be stored without spaces as well). As below..
"users" : {
"21JvDyuzNcbKTxGhCEyEzzSbwKc2" : {
"name" : "Gary Oose",
"number" : "123456789"
},
"F1AvstJCWqdzBWarXtxwcm01Ir02" : {
"name" : "Tina Urtle",
"number" : "987654321"
},
"KNTJdnKaE3amJ79LOq40ztKWBWp2" : {
"name" : "Tommy Adpole",
"number" : "121212121"
}
}
If I wanted to keep the spaces in the number strings, I could have added a single space in the replace() to account for that.. replace(/\s/g, ' ')
Working with the data object below, I'm trying to write a function which takes in a name (the name being a label from the data, like in this case "GD"), and value. I want to use the function I have written below in underscore but I'm having a hard time trying to figure out how to write out this code, as I'm new to JS in general. Any input on how to modify the function getOption()?
var data = [{},{},
{
field:"ran",
indexable:true,
label:"R",
options: [
{},{},
{
category_value:"200",
label:"GD"
},{},{}
]
},{}
]
function getOption (name, value) {
return _.findWhere(data.options, {label: name}); //return the category_value of the name, if "GD" is the name, the output of this function should be 200
}
According to the docs,
_.findWhere(list, properties)
Looks through the list and
returns the first value that matches all of the key-value pairs listed
in properties.
If no match is found, or if list is empty, undefined will be returned.
_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
=> {year: 1918, newsroom: "The New York Times", reason: "For its public service in publishing in full so many official reports,
documents and speeches by European statesmen relating to the progress
and conduct of the war."}
Looks like you have to specify the property name, and property value. In this case, "label" and "GD" respectively.
Try this:
var data = [{},{},
{
field:"ran",
indexable:true,
label:"R",
options: [
{},{},
{
category_value:"200",
label:"GD"
},{},{} // why so many initalized empty arrays?
]
},{}
]
function getOption (name, value) {
return _.findWhere(data.options, {label: "GD"}); // returns the whole array
// try var result = _.findWhere(data.options, {label: "GD"});
// then return result.category_value;
}
Just recommended the following url to somewhat related post. It might be of use for you, and it doesn't use an additional library: dynamic access to an array in javascript
I have a casperjs script which iterates over a list of pages and extracts data.
On the other hand I have a csv file with 2 fields 'ean' 'ref' which I parse with Papa.parse. The output is an object. I am looking for a solution to query an javascript object (the output from Papa.parse) for the 'ref' field and extract the 'ean'. I thought .filter() is what i was looking for but that can only search for a predefined value in the callback function.
function cd(element) {
return element == '123';
}
var b = c.filter(cd);
The problem hear is 1. It returns an empty array and 2. even if it would work I need to change the value with every call since I want to find the ean value for any given ref.
function cd(element,ref) {
return element == ref;
}
This is the data I need to search
"data": [
{
"ean": "654321",
"ref": "123"
},
{
"ean": "1234567",
"ref": "124"
}
]
I hope I made myself more clear. Thank you in advance
I used https://lodash.com/docs#where
Does exactly what i want
var a = _.where(array,{'ref' : 'value i am looking for'});
result is an array from where I can extract the value of the ean field.
Actually I want to search an attribute's value in an json array for one of its child. Now one condition is that the attribute will not be there in all the child's of the array. This is my json array.
[{
"heading1":"heading1",
"heading2":"heading2",
"heading3":"heading3",
"heading4":"heading4",
"heading5":"heading5",
"heading6":"heading6"
},
{
"column1":65536,
"column2":"school",
"column3":"testing purpose",
"column4":"DESKTOP",
"column5":"ACTIVE",
"column6":true,
"column7":"a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
},
{
"column1":98305,
"column2":"Nikhil",
"column3":"Test",
"column4":"LAPTOP",
"column5":"ACTIVE",
"column6":true,
"column7":"a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
}]
So presently I am working with the each loop but like this
var obj = $.parseJSON(JSON.stringify(response));
$.each(obj, function () {
console.log("heading1", this['heading1']);
});
Here response comes from mserver and it is the json array
Now I want to know can I search for this attribute in the json array without using a loop in jQuery.
Based on your sample code what I understand you have is an array of objects and you want to find objects with one specific property and or value:
This will return true if the object has the property
var results= arr.filter(function(item){ return item.hasOwnProperty("column5"); });
Or you can perform additional action when you find the property:
arr.filter(function(item){
if (item.hasOwnProperty("column5")) {
return item["column5"] === 'demo 01'; //or item.column5 === 'demo 01'
}
return false;
});
This only works on IE9+ if you need this to run in older versions of IE, please follow the instructions under polyfill:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
The you can check like
var obj = $.parseJSON(response);
$.each(obj, function (index,value) {
if(typeof obj[index].heading2 !== "undefined")
{
alert(obj[index].heading2);
}
when in other object of array element not find then it returns undefined. and you can check like that.
you can check in this http://jsfiddle.net/gKRCH/
It's best to use a loop. But if the format of the JSON is regular, you could regex for the value in the response string.
I'm not recommending this method, just pointing out that it exists.
var value = "heading1";
if( (new RegExp('"' + value + '"')).test(response) ){
// Found value
};
Here, we take the required value, wrap it in quotation marks and search for it in the response.
This has several issues, such as:
It might find the pattern in a property name
If the value could contain regex special characters, they'll need escaping.
If your JSON contains values with escaped quotation marks, you could get a false positive from partial matches.
That's why it depends on you knowing the format of the data.
EDIT:
You can solve issue 2 by using this condition instead of regex. But it gives you less flexibility.
response.indexOf('"' + value + '"') !== -1
Try this,
$.each(object,function(key, value){
console.log(key);
console.log(value);
});
You can use this JS lib; DefiantJS (http://defiantjs.com). This lib extends the global object JSON with the method "search" - with which, you can perform XPath queries on JSON structures. Like the one you have exemplified.
With XPath expressions (which is standardised query language), you can find whatever you're looking for and DefiantJS will do the heavy-lifting for you - allowing your code to be neat and clean.
Here is the fiddle of this code:
http://jsfiddle.net/hbi99/q8xst/
Here is the code:
var data = [
{
"heading1": "heading1",
"heading2": "heading2",
"heading3": "heading3",
"heading4": "heading4",
"heading5": "heading5",
"heading6": "heading6"
},
{
"column1": 65536,
"column2": "school",
"column3": "testing purpose",
"column4": "DESKTOP",
"column5": "ACTIVE",
"column6": true,
"column7": "a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
},
{
"column1": 98305,
"column2": "Nikhil",
"column3": "Test",
"column4": "LAPTOP",
"column5": "ACTIVE",
"column6": true,
"column7": "a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
}
],
res = JSON.search( data, '//*[column4="DESKTOP"]' );
console.log( res[0].column2 );
// school