Accessing JSON elements from javascript - javascript

$.getJSON('http://23.21.128.153:3000/api/v1/holidays', function(data){
alert("this: " + data.holiday[0].name);
});
I'm trying to access the "name" attribute of the first element of my JSON response but without success, can anyone tell me what I'm doing wrong.

Try this:
data[0].holiday.name
The data looks like this:
[
{
"holiday":{
"id":1,
"date":"2012-05-01",
"name":"Dia del trabajo",
"description":"",
"country_id":1,
"moved_date":"2012-04-30"
}
},
{
"holiday":{...}
},
...]
So, you need to select the first element from the main array (data[0]), then get its holiday property (data[0].holiday), and then get its name property.

Related

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.

Printing Information from JSON string

I have the following JSON string:
var txt=
{
"people":
[{
"person":
{
"firstname":"Jane",
"lastname":"Doe"
}
},
{
"person":
{
"firstname":"John",
"lastname":"Smith"
}
}
]
};
I want the program to alert that there are two people in the list, but when I do my count function, it only says 1 (gets to 'people' then doesn't go deeper into the list).
Here is the fiddle:
http://jsfiddle.net/LipeeVora/rsBYb/3/
You don't need a to write a counting loop. txt.people.length will give you the count, as txt.people is an array object.
See my revised fiddle for an example: http://jsfiddle.net/rsBYb/5/
Your loop was counting the elements in txt - of which there is only one (the people array). It would work fine if you instead use txt.people in the loop. You really want to count the elements in txt.people, not txt.
Example of this: http://jsfiddle.net/rsBYb/8/
txt.people.length
will give you the correct answer
http://jsfiddle.net/rsBYb/6/
It is because you count people and not persons.
Change your loop to this:
for ( property in txt.person )
{
count++;
}
alert("count = " + count);
This should work:
txt.people.length
You might have to do a JSON.parse depending on where you're pulling your JSON string from (if you're doing anything with it outside of the fiddle)

adding variable values in json file using push function

I have a json file and two variables, i want to store the variables values in the json file using push function in json. my code is
var x=xmen;
var z=xmen website
var jsonObj = {
"items":
[
{
"title":"some title",
"url":"some url"
}
]
};
I want my resulting json file to be
var jsonObj = {
"items":
[
{
"title":"some title",
"url":"some url"
}
{
"title":"xmen",
"url":"xmen website"
}
]
};
I dont want to use arrays just while pushing the value using
jsonObj.items.push
i want to call the variable and assign like example
jsonObj.items.push({"title":+x+,"url":+url+}); //just to explain, its not the original function.
I don't think push is your problem. It's your object syntax that's messed up.
Instead of
{"title":+x+,"url":+url+}
Try this instead:
// Assuming that "x" and "url" are valid variables
{"title":x,"url":url}
Here's a quick demo of everything working: http://jsbin.com/zicofoye/1/edit
jsonObj.items.push({
"title":"avengers",
"url":"avengers website"
});

BackboneJS - get specific value from collection using _.max method

I want to get a specific value from a model inside a Collection. The Collection is sorted by ID (contest_id) which is served by the database and gets delivered as JSON. So, the JSON looks like:
data : [{
"contest_id" : "3",
"artist" : {
"artist_name": "some name",
"artist_cover" : "some image.jpg"
}
},
"contest_id" : "1",
....
}]
Now, I have glued something together:
var contestImage = _.max(this.collection.toJSON(), function(cnt){
return cnt.contest_id;
});
I get the highest contest_id, which is what I want but how do I proceed when I want to grab the image? and even display it?
Thanks in advance...
The max method should actually be available directly from your Backbone collection (although it's an Underscore method, it's mixed into Backbone's Collections), which means you can simplify your code a bit.
Something like this should do the trick:
var model = this.collection.max(function (cnt) {
return cnt.contest_id;
});
var contest_id = model.get('contest_id');
The first section returns the model you want, and the second gets the contest ID attribute.
To get the artist cover attribute, you can then convert it to JSON:
var artist_cover = model.toJSON().artist.artist_cover;
Or get the artist attribute from the model:
var artist_cover = model.get('artist').artist_cover;
This actually made it work:
var contestImage = _.max(this.collection.toJSON(), function(cnt){
return cnt.contest_id;
});
var latestImage = contestImage.artist.artist_cover;
Thanks for the answers though :-)

Changing nested attribute with model.set in Backbone

I'm trying to do what I hope is a simple thing -- doing a model.set only on a sub attribute of the object.
Right now, I have a model that looks like this:
{
"attr1" : true,
"attr2" : this.model.get("username"),
"attr3" : $('#tenant_select').val(),
"attr_array": [
{
"id": "sub_1",
"state": "active"
},
{
"id": "sub_22",
"state": "not_active"
}
]
}
I want to be able to grab reach into myMode.attr_array.state and change the value. However, using .set I've only been able to change attributes on the first level, i.e. attr_array.
Is there an way to do this using model.set?
You can do it (I'm wondering why you didn't manage to do it). But you have to be careful:
var array = this.get('attr_array');
array[1].state = 'active';
this.set('attr_array', array);
What's the problem here? Your model holds a reference of the object. Therefore the last line is useless, it won't change anything at all. It's simply equivalent to:
this.get('attr_array')[1].state = 'active';
And you lose any internal stuff Backbone does when you use set.
So what to do? Clone your object:
var array = _.clone(this.get('attr_array'));
array[1].state = 'active';
this.set('attr_array', array); // will trigger 'change' and 'change:attr_array' events

Categories

Resources