Javascript [Object object] error in for loop while appending string - javascript

I am a novice trying to deserialize my result from an onSuccess function as :
"onResultHttpService": function (result, properties) {
var json_str = Sys.Serialization.JavaScriptSerializer.deserialize(result);
var data = [];
var categoryField = properties.PodAttributes.categoryField;
var valueField = properties.PodAttributes.valueField;
for (var i in json_str) {
var serie = new Array(json_str[i] + '.' + categoryField, json_str[i] + '.' + valueField);
data.push(serie);
}
The JSON in result looks like this:
[
{
"Text": "INDIRECT GOODS AND SERVICES",
"Spend": 577946097.51
},
{
"Text": "LOGISTICS",
"Spend": 242563225.05
}
]
As you can see i am appending the string in for loop..The reason i am doing is because the property names keep on changing therefore i cannot just write it as
var serie = new Array(json_str[i].propName, json_str[i].propValue);
I need to pass the data (array type) to bind a highchart columnchart. But the when i check the var serie it shows as
serie[0] = [object Object].Text
serie[1] = [object Object].Spend
Why do i not get the actual content getting populated inside the array?

You're getting that because json_str[i] is an object, and that's what happens when you coerce an object into a string (unless the object implements toString in a useful way, which this one clearly doesn't). You haven't shown the JSON you're deserializing...
Now that you've posted the JSON, we can see that it's an array containing two objects, each of which has a Text and Spend property. So in your loop, json_str[i].Text will refer to the Text property. If you want to retrieve that property using the name in categoryField, you can do that via json_str[i][categoryField].
I don't know what you want to end up with in serie, but if you want it to be a two-slot array where the first contains the value of the category field and the second contains the value of the spend field, then
var serie = [json_str[i][categoryField], json_str[i][valueField]];
(There's almost never a reason to use new Array, just use array literals — [...] — instead.)

Related

What is the correct way to handle this data using jQuery?

I have a list of html elements with data attributes, which I would like to assemble into a jQuery object and manipulate the values.
What is the best way to dynamically add these in an each loop so that I can easily access the data as so: data.name and data.name.prop?
I want all the naming conventions to be dynamic and based on the data.
I based my code on the top answer from here: How to create dynamically named JavaScript object properties?
So far I have:
$('.licences-list .data div').each(function(index) {
var data = {}
cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
cats.push(data)
})
But when I try to iterate over the data array, like so:
$.each(cats, function(key, value){
$('<div class="card"><p>'+value+'</p></div>').appendTo('#commercial-licenses');
});
I just get [object Object] output... and I'm not sure why!
var data = {}
cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
Each time you loop through, you're actually just adding an empty object (data) to your array (cats). You're then assigning a named property to that array (cats) which $.each has no idea about (it ignores them because it's iterating over an actual array).
My guess is you want an object map which is something like: var cats = { "f1": "feline 1", "f2": "feline " };
In that case what you want is:
var cats = {};
$('.licences-list .data div').each(function(index) {
cats[$(this).find('p').data('cat')] = $(this).find('p').data('catname')
})
If you want an array that contain more values than just strings (or whatever data you have added to the element), you create new objects each time and append them to the cats array:
var cats = [];
$('.licences-list .data div').each(function(index) {
cats.push({
'id': $(this).find('p').data('cat'),
'name': $(this).find('p').data('catname')
});
})
This will then give you an array that you can use $.each over, and access the values using: value.id, value.name
Don't over complicate it.
$('.div').attr('data-attribute', 'data-value');
using your example:
$('.licences-list .data div').attr('attribute-name', 'attribute-value');

Parsing JSON and loading into array

JSON-https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo
I am trying to take the JSON from the above link and place it in the following format(date,open,high,low,close)...
[
[1277424000000,38.58,38.61,37.97,38.10],
[1277683200000,38.13,38.54,37.79,38.33],
[1277769600000,37.73,37.77,36.33,36.60],
[1277856000000,36.67,36.85,35.72,35.93],
]
The date does not need to be Epoch time.
My code....
$.getJSON('https://www.alphavantage.co/query?
function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo', function(data) {
//Get the time series data
var timeseries = data['Time Series (Daily)']
var ohlcarray = [];
//Loop through each time series and convert it to JSON format
$.each(timeseries, function(key, value) {
var ohlcdata=[];
ohlcdata[0]=value[0];//date
ohlcdata[1]=value[1];//open
ohlcdata[2]=value[2];//high
ohlcdata[3]=value[3];//low
ohlcdata[4]=value[4];//low
ohlcarray.push(ohlcdata);
});
console.log(ohlcarray[0]);//test if worked properly
});
The output....
[undefined, undefined, undefined, undefined, undefined]
value[x] returns undefined. Any ideas on why this happens?
Thanks!
The reason is that in the each loop, the value is not a list but an object. To access it, you'd have to grab it using keys.
ohlcdata[0] = key; //date
ohlcdata[1] = value['1. open']; //open
ohlcdata[2] = value['2. high']; //high
ohlcdata[3] = value['3. low']; //low
ohlcdata[4] = value['4. close']; //low
https://jsfiddle.net/koralarts/7c2fkf93/2/
At this point it is already JSON. As Patrick mentioned, getJSON automatically parses json. You will need to access it with the array bracket notation since there are spaces in the property name.
var timeSeries = data['Time Series (Daily)'];
See ex: https://jsfiddle.net/dz0phhn2/6/

Knockout JS [Object object] pulling properties

I have an object in my JS sliced from an array:
self.deploysToDevId = ko.computed(function() {
var deployToDev = ko.utils.arrayFilter(self.builds(), function(build) {
return build.buildType() == 'Deploy to Development';
}, self);
var deployToDevID = deployToDev.slice(0,1).id
return deployToDevID;
});
This object is originally from an array called builds and is a build object. However, I am trying to get a property, the "id" of the build which is a property of build, and I want to be able to store this and return this as an object, however when I do the data-bind prints the text [Object object]
self.getIdOfMostRecentDeploy = ko.computed(function() {
var idOfMostRecentDeploy = (self.deploysToDevId().id);
return idOfMostRecentDeploy;
});
This should store the id of the object as "idOfMostRecentDeploy" but it is not doing so.
self.deploysToDevId = ko.computed(function() {
var deployToDev = ko.utils.arrayFilter(self.builds(), function(build) {
return build.buildType() == 'Deploy to Development';
},
self);
var deployToDevID = deployToDev[0];
return deployToDevID;
});
This is another way I have tried, this time trying to take the first object in the array and assign its id to a variable. although, I still just get [Object object]
when you do this:
self.deploysToDevId = ko.computed(function() {
var deployToDev = ko.utils.arrayFilter(self.builds(), function(build) {
return build.buildType() == 'Deploy to Development';
}, self);
var deployToDevID = deployToDev.slice(0,1).id
return deployToDevID;
});
you are creating a computed that will contain just the id of the deployToDev object, which I presume is an observable (that is, a javascript function you need to eval to get the value)
Then, when you try to access it using:
(self.deploysToDevId().id)
this is returning basically nothing, because the "id" you are looking for is in the computed itself, self.deploysToDevId(), not in any inner id property
EDIT:
I have created this fiddle that may help you:
https://jsfiddle.net/r88zkn11/
in you case the only difference is that the object instead if having id and buildType as string objects, they are functions, so if you have to use them you have to evaluate them (use buildType() instead of buildType)
When you do this:
var deployToDevID = deployToDev.slice(0,1).id;
You are saying: give me an array one element long, and take the id property of that array. The array doesn't have an id property. Instead, you should be indexing the first element:
var deployToDevID = deployToDev[0].id;
Then, as JulioCT notes, the computed will return the id. It doesn't have an id member, it's just the id.
In your last example, you take the first element but don't take its id property, so naming it deployToDevID is misleading. Take the id of it as I suggest above, and then use deployToDevID anywhere you want to use that id.

Turn Observable Array into nested JSON

I'm having a problem getting an array of information stored properly as JSON.
I made a fiddle to illustrate the problem. Enter a set of tags and take a look at the console to see the output.
More explanation:
So I have an input that takes in a comma-separated list of tags, which I then format.
function createTagArray() {
// given an input value of 'tag1, tag2, tag3'
// returns array = ['tag1', 'tag2', 'tag3']
}
I thought what I needed to do next was the following:
loop over the array and create a 'tag' object for each item which also includes an id for the tag and the id of the contact the tag is associated with.
Each object is pushed to tags, an observable array.
function single_tag(id, contactId, tagLabel) {
var self = this;
self.id = id;
self.contactId = contactId;
self.tagLabel = tagLabel;
}
function createTags() {
var array = createTagArray();
for (var i = 0; i < array.length; i++) {
self.tags().push(new single_tag(uuid.generate(), self.contactId, array[i]));
}
}
Then, I converted it into JSON
self.contactInformation = function() {
return ko.toJS({
"id": self.contactId,
"firstname": self.firstname(),
"lastname": self.lastname(),
... other fields ...
"tags": self.tags(),
})
}
But, when I inspect the console output of calling this function, tags is a collection of arrays, not a nice json object.
How do I get it formatted correctly?
I tried this suggestion, and the tag json is structured correctly, but it is stored with escaped quotes, so that seems wrong.
Thanks for all the help!
I would recommend you knockout.mapping plugin for KO, it allow map complicated JSON structure to view model, even without declarations.
From the documentation
Let’s say you have a JavaScript object that looks like this:
var data = {
name: 'Scot',
children: [
{ id : 1, name : 'Alicw' }
]
}
You can map this to a view model without any problems:
var viewModel = ko.mapping.fromJS(data);
Now, let’s say the data is updated to be without any typos:
var data = {
name: 'Scott',
children: [
{ id : 1, name : 'Alice' }
]
}
Two things have happened here: name was changed from Scot to Scott and children[0].name was changed from Alicw to the typo-free Alice. You can update viewModel based on this new data:
ko.mapping.fromJS(data, viewModel);
And name would have changed as expected. However, in the children array, the child (Alicw) would have been completely removed and a new one (Alice) added. This is not completely what you would have expected. Instead, you would have expected that only the name property of the child was updated from Alicw to Alice, not that the entire child was replaced!
...
To solve this, you can specify which key the mapping plugin should use to determine if an object is new or old. You would set it up like this:
var mapping = {
'children': {
key: function(data) {
return ko.utils.unwrapObservable(data.id);
}
}
}
var viewModel = ko.mapping.fromJS(data, mapping);
In the jsfiddle you were using Knockout 3.0 which doesn't have support for textInput. This was added in 3.2. To use version 3.2 you need to use a cdn such as this: http://cdnjs.com/libraries/knockout
There was typeo in your binding. sumbit should be submit.
There was a problem with your constructor for single_tag. id was not used so I removed it:
function single_tag(contactId, tagLabel) {
var self = this;
self.contactId = contactId;
self.tagLabel = tagLabel;
}
Currently also contactId is not set because the observable has not been set to a value.
To convert to JSON you need to use ko.toJSON instead of ko.toJS:
self.contactInformation = function() {
return ko.toJSON({
"firstname": self.firstname(),
"tags": self.tags(),
})
}
Now when the console writes out an array appears:
{
"firstname":"test",
"tags":[
{"tagLabel":"test1"},
{"tagLabel":"test2"},
{"tagLabel":"test3"}
]
}
JsFiddle
So my problem was more basic than I was realizing. I'm using JSON Server to serve up my data, and I was pulling information from two parts of the database (contacts & tags).
When I tried to update my tags, I was trying to apply them to a property that didn't exist on the contact JSON in my database. Posting the tags separately worked though.

extract single variable from JSON array

I hope my question is not as stupid as I think it is...
I want to extract (the value of) a single variable from an JSONarray. I have this jquery code
$(document).ready(function(){
$("#gb_form").submit(function(e){
e.preventDefault();
$.post("guestbook1.php",$("#gb_form").serialize(),function(data){
if(data !== false) {
var entry = data;
$('.entries').prepend(entry);
}
});
});
});
the content of data looks like this ("MyMessage" and "MyName" are values written in a simple form from user):
[{"message":"MyMessage","name":"MyName"}]
the var "entry" should give (more or less) following output at the end:
"Send from -MyName- : -MyMessage-"
I'm not able to extract the single array values from data. I tried things like that:
var message = data['message'];
var name = data['name']
var entry = "Send from" + name + ":" +message;
but that gives "Send from undefined: undefined"
Hope you can help me with that.
you can do like this to get first item of array:
var msg = "Send from"+data[0].name + " "+data[0].message;
console.log(msg );
SAMPLE FIDDLE
UPDATE:
as you are using $.post you will need to explicitly parse response as json:
$.post("guestbook1.php",$("#gb_form").serialize(),function(data){
var response = jQuery.parseJSON(data);
var msg = "Send from"+response [0].name + " "+response [0].message;
console.log(msg );
});
To access an array you use the [] notation
To access an object you use the . notation
So in case of [{JSON_OBJECT}, {JSON_OBJECT}]
if we have the above array of JSON objects in a variable called data, you will first need to access a particular Json Object in the array:
data[0] // First JSON Object in array
data[1] // Second JSON Object in array.. and so on
Then to access the properties of the JSON Object we need to do it like so:
data[0].name // Will return the value of the `name` property from the first JSON Object inside the data array
data[1].name // Will return the value of the `name` property from the second JSON Object inside the data array

Categories

Resources