Get Child JSON Values from Objects - javascript

I have an endpoint with two JSON Objects as follows:
{
"main" {
"id": 1,
"title": Main Title,
},
{
"secondary" {
"id": 3,
"title": Secondary Title,
},
I am using backbone and have the following $each function, but using dot notation, I can't seem to be able to browse to the titles (ex. main.title or secondary.title). What am I missing?
var collection = new contentArticles([], { id: urlid });
collection.fetch({
dataType: "json",
success: function (model, response) {
console.log(response);
$.each(response, function (index, value) {
console.log(value.main.title);
$("#test2").append('<li>' + value.main.title + '</li>');
});
In my console, it gives an error of: Uncaught TypeError: Cannot read property 'title' of undefined

Assuming your JSON is actually valid when returned (it isn't valid the way you show it), try
$("#test2").append('<li>' + value.title + '</li>');
Your actual JSON should look like:
{
"main": {
"id": 1,
"title": Main Title,
},
"secondary": {
"id": 3,
"title": Secondary Title,
}
}
If you just want the value of main, instead of using $.each(), remove that entire block and do:
$("#test2").append('<li>' + response.main.title + '</li>');
And your final code would look something like:
var collection = new contentArticles([], { id: urlid });
collection.fetch({
dataType: "json",
success: function (model, response) {
console.log(response);
if (response.main.title !== 'undefined'){
$("#test2").append('<li>' + value.main.title + '</li>');
}else{
console.log('Main is undefined');
}
}
});
Final Edit: It looks like you want JSON like:
{
"main": [{
"id": 1,
"title": "Main Title"
}, {
"id": 2,
"title": "Main Title 2"
}, {
"id": 3,
"title": "Main Title 3"
}],
"secondary": [{
"id": 5,
"title": "Secondary Title 5"
}, {
"id": 34,
"title": "Secondary Title 34"
}, {
"id": 36,
"title": "Secondary Title 36"
}]
}
If that is the case your code would look like:
var collection = new contentArticles([], { id: urlid });
collection.fetch({
dataType: "json",
success: function (model, response) {
console.log(response);
$.each(function(index, value){
$.each(item_index, item_value){
$("#test2").append('<li>' + item_value.title + '</li>');
}
});
}
});

The problem lies with input JSON, it should be
{
"main" :{
"id": 1,
"title": "Main Title"
},
"secondary":{
"id": 3,
"title": "Secondary Title"
}
}

Related

Loop through a nested JSON object to find a value id

"results": {
"data": {
"facets": {
"60749428": {
"id": 60749428,
"name": "KC Content Content Kind"
},
"60750276": {
"id": 60750276,
"name": "KC Content Product Version"
},
"69107204": {
"id": 69107204,
"name": "KC Video Audience"
},
"69127027": {
"id": 69127027,
"name": "KC Content Kind ID"
}
}
}
}
I want to loop through this nested json object by going into the facet object and say if the name attribute is "KC Content Kind ID" then return the id for that corresponding name attribute
So after getting my api call with postman I was trying to get the corresponding id of the "KC Content Kind ID" in my success function this way, but since its not an array I was wondering if each will work in jquery.
//Get Available Kinds
function getAvailableKinds() {
$.ajax({
url: csexe + "/api/v2/facets/" +getLocationId(),
dataType: "json",
type: "GET",
beforeSend: function(xhr) {
xhr.setRequestHeader ("OTCSticket", getAuthToken());
},
success: function(response) {
var obj = response.results.data.facets;
$.each(obj, function(item, value){
if ( value == 'KC Content Kind ID') {
var idRequired = obj.id;
}
});
},
error: function(jqXHR, textStatus, errorThrown){
alert("An error occurred... Look at the console");
$("body").html('<p>status code: '+jqXHR.status+'</p><p>Error Thrown: ' + errorThrown + '</p><p>Response Text:</p><div>'+jqXHR.responseText + '</div>');
}
});
Just parse the string over and then do a simple loop.
var jsonObj = (JSON.parse("your json here")).data.facets;
for (i = 0; i<jsonObj.length;i++)
{
if(jsonObj[i].name == "KC Content Kind ID")
return jsobObj[i].id;
}
you can use Object.keys and find
const obj = {"results": {"data": {"facets": {"60749428": {"id": 60749428,"name": "KC Content Content Kind"},"60750276": {"id": 60750276,"name": "KC Content Product Version"},"69107204": {"id": 69107204,"name": "KC Video Audience"},"69127027": {"id": 69127027,"name": "KC Content Kind ID"}}}}};
const facets = obj.results.data.facets;
const result = Object.keys(facets).find(v => facets[v].name === 'KC Content Kind ID');
//your object keys are equal to id, you can just return key
console.log(result);
// if your object keys can be different from id you can do this
console.log(facets[result].id);
I think the easiest way to achieve this would be by using Object.values function in conjunction with Array.prototype.filter. You can then take the first item from the array returned by the filter method (since each ID should be unique) and display it's ID.
const o = { "results": { "data": { "facets": { "60749428": { "id": 60749428, "name": "KC Content Content Kind" }, "60750276": { "id": 60750276, "name": "KC Content Product Version" }, "69107204": { "id": 69107204, "name": "KC Video Audience" }, "69127027": { "id": 69127027, "name": "KC Content Kind ID"}}}}};
const [a] = Object.values(o.results.data.facets).filter(f => f.name == "KC Content Kind ID");
console.log(a.id);
var obj = {
"results": {
"data": {
"facets": {
"60749428": {
"id": 60749428,
"name": "KC Content Content Kind"
},
"60750276": {
"id": 60750276,
"name": "KC Content Product Version"
},
"69107204": {
"id": 69107204,
"name": "KC Video Audience"
},
"69127027": {
"id": 69127027,
"name": "KC Content Kind ID"
}
}
}
}
};
let facets = obj.results.data.facets;
let id;
for(let key in facets){
if(facets[key].name == 'KC Content Kind ID'){
id = facets[key].id;
break;
}
}
console.log(id);

How can I avoid options if those options are previously selected in vue js html?

My json data for getting all inventories is
{
"status": true,
"data": [
{ "inv_id": 1, "name": "Arts" },
{ "inv_id": 2, "name": "web" },
{ "inv_id": 3, "name": "mobileapp" },
{ "inv_id": 4, "name": "ws" },
{ "inv_id": 5, "name": "aop" },
{ "inv_id": 6, "name": "bin" },
{ "inv_id": 7, "name": "webs" },
{ "inv_id": 8, "name": "hell" }
]
}
My json data which is selected already by user will be in the following format
{
"data": {
"pid": 109,
"contact": {
"email": "ew98#gmail.com",
"phone": 85998472,
"address": { "country": "India", "state": "Kerala" }
},
"about": "hello how are you",
"is_featured": false,
"avg_rating": 0,
"total_reviews": 0,
"reviews": [],
"inventory": [
{
"item": {
"name": "Arts",
"category": { "name": "Education", "id": 1 },
"id": 1
}
}
],
"review": null
},
"status": true
}
Here arts is already selected, so I need to avoid the same when I am giving an edit option. How can I able to achieve the same.
mounted() {
var self = this
data = {}
data["auth-token"] = this.authType
data["pid"] = this.pid
$.ajax({
url: "http://127.0.0.1:8000/get/post/",
data: data,
type: "POST",
dataType: "json",
success: function(e) {
if (e.status == 1) {
self.inventory = e.data.inventory
data = {}
data["category"] = self.catid
data["cat_id"] = self.catid
$.ajax({
url: "http://127.0.0.1:8000/alpha/get/inventory/",
data: data,
type: "POST",
dataType: "JSON",
success: function(e) {
if (e.status == 1) {
self.inventoryall = e.data
}
},
})
}
},
})
}
I have all inventories in inventoryall[] and inventory that is already added in inventory[].
My html code is
<div class="form-group">
<label>Inventory
<small>(required)</small>
</label>
<select
id="basic"
class="selectpicker"
data-live-search="true"
data-live-search-style="begins"
title="Select Your Subcategory"
v-model="inv" name="inv[]" multiple required="required"
>
<option v-for="sop in inventoryall" v-bind:value="sop.inv_id">{{sop.name}}</option>
</select>
</div>
So, when I display the inventories here, I need to avoid the once that is already selected. Please help me to have a solution.
Here you can use the array filter method:
// filter loops through every item in the array and returns a new array
// if the filter function returns true, the item stays in the new array
// if the filter function returns false, the item is removed
self.inventoryall = self.inventoryall.filter(item => {
// loop through all of the currently selected items
for (const selectedItem of self.inventory) {
// if we find a current item with the same ID as the selected one,
// return false, so we don't keep the item
if (selectedItem.id === item.inv_id) {
return false
}
}
// if we never find an item with a matching ID, return true to keep it
return true
})
Note that this method is only available in browsers that support ES6, so use the polyfill on the MDN page if you need to support older browsers.
Another note, since you're using Vue, this would probably be a good use case for a computed property.

Deleting a key in JSON while making ajax call from javascript

I am new to java script and ajax. I have a JSON and I want to remove outputs cell in this JSON:
{
"cells": [{
"metadata": {
"trusted": true,
"collapsed": false
},
"cell_type": "code",
"source": "print(\"hi\")",
"execution_count": 1,
"outputs": [{
"output_type": "stream",
"text": "hi\n",
"name": "stdout"
}]
},
{
"metadata": {
"trusted": true,
"collapsed": true
},
"cell_type": "code",
"source": "",
"execution_count": null,
"outputs": []
}
],
"metadata": {
"kernelspec": {
"name": "Python [Root]",
"display_name": "Python [Root]",
"language": "python"
},
"anaconda-cloud": {},
"language_info": {
"pygments_lexer": "ipython3",
"version": "3.5.0",
"codemirror_mode": {
"version": 3,
"name": "ipython"
},
"mimetype": "text/x-python",
"file_extension": ".py",
"name": "python",
"nbconvert_exporter": "python"
},
"gist": {
"id": "",
"data": {
"description": "Untitled5.ipynb",
"public": true
}
}
},
"nbformat": 4,
"nbformat_minor": 0
}
and this is my attempt on removing the outputs cell. This piece of code posts the data to above mentioned JSON:
"use strict";
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
var outputs = data.cells;
var data_dup = _objectWithoutProperties(data, ["outputs"]);
var id_input = $('#gist_id');
var id = params.gist_it_personal_access_token !== '' ? id_input.val() : '';
var method = id ? 'PATCH' : 'POST';
// Create/edit the Gist
$.ajax({
url: 'https://api.github.com/gists' + (id ? '/' + id : ''),
type: method,
dataType: 'json',
data: JSON.stringify(data_dup),
beforeSend: add_auth_token,
success: gist_success,
error: gist_error,
complete: complete_callback
});
};
But this code doesnt work. Can some one please guide how can we directly strip a key(outputs in this case) from ajax call and post it to JSON.
This is a gist extension of jupyter notebook and I am trying to strip output while posting it to gist on github
function _objectWithoutProperties(obj, key="outputs") { obj.cells.forEach(cell=>delete(cell[key])); }
If you use ES6, you can use this syntax to remove outputs:
{
...data,
cells: data.cells.map(({ outputs, ...otherProps }) => otherProps),
}
Note: data is your complete object.

Node.js loop through nested Javascript object

I want to have posts + attachments from Facebook so I can create a list of posts. The problem is that I want to put attributes: id, message and any attachment in a array for every post feed. I'm not sure whether I need to iterate objects inside a array or can I select the ID and get the related information.
Also I'm using async.waterfall() to get synchronous calls because I will make other calls that depend on the previous call.
I tried this to get the id, message and src url of attachment:
var async = require("async");
var graph = require('fbgraph');
async.waterfall([
getFeed,
getPostPicture,
], function (err, result) {
});
function getFeed(callback) {
graph.get("/.../feed" + "?fields=message,attachments&access_token=APPID|APPSECRET", function(err, res) {
callback(null, res);
});
}
function getPostPicture(arg1, callback) {
var feedData = arg1.data;
for(var i in feedData)
{
var id = feedData[i].id;
var message = feedData[i].message;
var feedAttachment = feedData[i].attachments
for (var j in feedAttachment)
{
var attachment = feedAttachment.data;
var attachmentURL = attachment[i].src;
for (var j in attachmentURL)
{
var attachmentURL = feedAttachment.src;
}
}
}
console.log(attachment);
}
Above will output:
[ { description: 'post message 1',
media: { image: [Object] },
target:
{ id: '...',
url: 'https://www.facebook.com/.../photos/a............/.../?type=3' },
title: 'Timeline Photos',
type: 'photo',
url: 'https://www.facebook.com/.../photos/a............/.../?type=3' } ]
Below is the response where I first called graph.get in the source code
and I need { data -> [message, id, attachments -> data[src] ]}
{
"data": [
{
"message": "post message 1",
"id": "..._...",
"attachments": {
"data": [
{
"description": "picture 1",
"media": {
"image": {
"height": 256,
"src": "https://scontent.xx.fbcdn.net/v/t1.0-9/..._..._..._n.png?oh=...&oe=...",
"width": 256
}
},
"target": {
"id": "...",
"url": "https://www.facebook.com/.../photos/a............/.../?type=3"
},
"title": "Timeline Photos",
"type": "photo",
"url": "https://www.facebook.com/.../photos/a............./..../?type=3"
}
]
}
},
{
"message": "Test status update 123",
"id": "..._..."
}
],
"paging": {
"previous": "https://graph.facebook.com/v2.8/.../feed?fields=message,attachments&format=json&since=...&access_token=...&limit=25&__paging_token=enc_...&__previous=1",
"next": "https://graph.facebook.com/v2.8/.../feed?fields=message,attachments&format=json&access_token=...&limit=25&until=...&__paging_token=enc_..."
}
}
When you are using the for loop in getPostPicture function, the i variable is actually the element in the array feedData, so you have to i.id or i.attachments and i.message. Also I think since you are using same j in 2 loops with one nested inside the other, it also won't work properly, so you might have to change that also, and explain you question with the kind of output you are expecting.

C# ListItemCollection to JSON, while keeping values and text items

I have created a web service (asmx file) that returns a serialized ListItemCollection with the following code.
public string getStates(string Country)
{
ListItemCollection lic = DBInterface.GetStates(Country);
var serialized = JsonConvert.SerializeObject(lic);
return serialized;
}
I call the web service via javascript when a user selects a country from a dropdown list using the following code.
//ajax function that uses web services to get states
function GetStates(val)
{
$.ajax({
type: "POST",
url: "/WebServices/getServerData.asmx/getStates",
data: JSON.stringify({Country: val}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#ddlState").empty();
var parsed = JSON.parse(data.d);
for (var i = 0; i < parsed.length; i++) {
$("#ddlState").append("<option value='" + parsed[i] + "'>" + parsed[i] + "</option>");
}
},
error: function (data) {
alert(data.status + " " + data.statusText);
}
});
}
The issue is that I want to also keep not only the ListItemCollection text, but also it's value. However the "JsonConvert.SerializeObject only returns the text items. Can someone help to return the value and text so that I can populate the dropdown via javascript?
Thanks!
One thing you can use the JavaScriptSerializer() in System.Web.Script.Serialization:
ListItemCollection lic = new ListItemCollection() {
new ListItem("Display Text", "val1"),
new ListItem("Display Text 2", "val2"),
};
var ser = new JavaScriptSerializer();
var serialized = ser.Serialize(lic);
Results in (I took the liberty to format) :
[
{
"Attributes": {
"Keys": [],
"Count": 0,
"CssStyle": {
"Keys": [],
"Count": 0,
"Value": null
}
},
"Enabled": true,
"Selected": false,
"Text": "Display Text",
"Value": "val1"
},
{
"Attributes": {
"Keys": [],
"Count": 0,
"CssStyle": {
"Keys": [],
"Count": 0,
"Value": null
}
},
"Enabled": true,
"Selected": false,
"Text": "Display Text 2",
"Value": "val2"
}
]

Categories

Resources