Postman - Retrieve all values from Nested JSON in a list - json

I am using Postman to run some APIs and get response. There is 1 API where I get the response:
{
"Id": 412,
"properties": {
"instruction01": "RFI100044",
"instruction02": "RFI100107",
"instruction03": "RFI100127",
}
}
What I want:
Get values from all the attributes containing text "instruction" and put it in a list (which I will use later) OR
To get all the values(instruction01,instruction02..) from "properties" attribute and put it in a list and access from the list then.
How can I achieve this?

You can try
const res = pm.response.json();
let keys = Object.keys(res.properties);
let values = [];
keys.forEach((element) => {
values.push(res.properties[element]);
});
console.log(values);
//["RFI100044", "RFI100107", "RFI100127"]

Related

Parsing JSON to get only specific children not all the children

I have been trying to parse the following JSON data using JSON.Parse(), I only need the url tags inside images not the caption or resizedImageUrls.
{"images": [
{
"url": "https://media.IMG_0001.jpg",
"caption": "Photo1",
"resizedImageUrls": {
"size135x100": "https://media.IMG_0001_135x100.jpg",
"size476x317": "https://media.IMG_0001_476x317.jpg",
"size656x437": "https://media.IMG_0001_656x437.jpg"
}
},
{
"url": "https://media.IMG_0002.jpg",
"caption": "Photo2",
"resizedImageUrls": {
"size135x100": "https://media.IMG_0002_135x100.jpg",
"size476x317": "https://media.IMG_0002_476x317.jpg",
"size656x437": "https://media.IMG_0002_656x437.jpg"
}
},{
"url": "https://media.IMG_0003.jpg",
"caption": "Photo3",
"resizedImageUrls": {
"size135x100": "https://media.IMG_0003_135x100.jpg",
"size476x317": "https://media.IMG_0003_476x317.jpg",
"size656x437": "https://media.IMG_0003_656x437.jpg"
}
}
]}
I declared the above JSON as variable data and then used following code.
var items = JSON.parse(data);
return {
url: items.images;
}
But it returned all the urls, captions and resized image urls. I know another method is to use items.images[0].url. But, sometimes there are lots of image urls and its not feasible to add codes from 0 to n numbers. I thought about using for loop, but, I dont know how.
You can make a map and return urls only.
const items = JSON.parse(data);
const urls = items.images.map(item => item.url);

Retrieve values from JSON response, and create a drop-down

I'm trying to get each of of the values inside my JSON file but when I run my API I get [Object Object] instead of what is inside the JSON.
This is my API request:
getAllvalues(): Observable<string[]> {
return this.http
.get<string[]>(this.Url + 'api');
}
my component.ts
this.ddvService.getAllvalues()
.subscribe(response => {
this.slots = response;
console.log (this.slots)
});
Example of my JSON response:
[
{
"AB": "http:"
},
{
"DE": "http:"
},
{
"CE": "http:"
},
{
"HI": "http:"
}
]
How can I get the value inside the JSON, and create a dropdown box with each of them?
Your example JSON is a pretty bad example: each object in the array in the JSON should have at least somewhat matching key names. In your case, the keys are "AB", "DE", "CE", "HI" - all different, which is quite uncommon in real-life. A more realistic JSON response would have matching key names, e.g.:
[
{
"id": "1",
"description": "Some description"
},
{
"id": "2",
"description": "Another description"
}
]
Now to answer your questions:
You are getting [Object Object] because you are trying to use an entire object as a literal value. Instead, you should access the individual keys/values of an object. For example: console.log(slots[0].id) - this should output 1.
Also, as indicated in the comments, replace Observable<string[]> with Observable<any[]> and get<string[]> with get<any[]>.
To create a drop-down in Angular, in your component template you can try this, assuming your slots value is the JSON above:
<select *ngIf="slots" name="slots">
<option *ngFor="let slot of slots" value="slot.id">{{ slot.description }}</option>
</select>
Also, to print the entire object to console in a readable form, instead of just console.log(this.slots);, you can try console.log(JSON.stringify(this.slots));
As mentioned in the comments above it is not ideal to have json like you have, my assumption is you might want to log keys instead of values, since value is same for all the objects in array. In that case you might want to try something like this.
1. Add any[] instead string[].
2.Add nested for loop to console.log your object array.
getAllvalues(): Observable<string[]> {
return this.http
.get<any[]>(this.Url + 'api');
}
this.ddvService.getAllvalues()
.subscribe(response => {
this.slots = response;
for(let i in this.slots)
{
let currentObj = this.slots[i]; // example of first in array { AB : "http:"}
for ( let z in currentObj )
{
if(currentObj[z]=== "http:") // we are trying to find key instead value
{
console.log(z); // it will log AB, DE, CE, HI ..
}
}
}
});

Should I convert JSON to Array to be able to iterate it with v-for?

In the following code I am getting data from server and filling array with them:
Vue.http.post('/dbdata', DataBody).then((response) => {
App.$refs.userContent.rasters_previews_list.$set(response); // putting JSON answer to Component data in userContent
console.log("App.$refs.userContent.rasters_previews_list: ", App.$refs.userContent.rasters_previews_list.length);
}, (response) => {
console.log("Error")
});
Now I am filling. data is declared in var userContent = Vue.extend({. I am using App.$refs.userContent.rasters_previews_list to set it's value, because one man from SO said that there is no other way to get access to constructor. I tried to do output of rasters_previews_list after changing with watch, but here is what I am see. http://img.ctrlv.in/img/16/08/04/57a326e39c1a4.png I really do not understand am I setting it's right way or no. If yes, why I do not see data and see only this crap?
data: function () {
return {
rasters_previews_list: []
}
}
But How I can iterate it with v-for?
<ul v-for="img in rasters_previews_list">
<li>{{img}}</li>
<ul>
This code is display one bullet. So it's look like it's assume that there is one object.
My object in browser console look like:
Object {request: Object, data: Array[10], status: 200, statusText: "OK", ok: true}
Your setting the full response instead of just the data you actually need.
Vue.http.post('/dbdata', DataBody).then((response) => {
App.$refs.userContent.rasters_previews_list.$set(response.data);
console.log("App.$refs.userContent.rasters_previews_list: ", App.$refs.userContent.rasters_previews_list.length);
}, (response) => {
console.log("Error")
});
If this isn't what you are looking for please post a full example.

Access object property while working with another object in ng-repeat

In my project I got a JSON response via GET request. The subTopics will be selected by the user and stored. Afterwards I send a POST request to the server with the selected ids.
Example JSON1: (from GET request)
{
"TopicList" :
[{
"id": "1234",
"name": "topic1",
"number": "1",
"subTopics": [
{
"id": "4567",
"name": "subTopic1.1",
"number": "1.1"
},
{
"id": "9876",
"name": "subTopic1.2",
"number": :1.2"
}
]
}]
}
In the POST response I get another JSON object from the server, which I have to show in my HTML view as a table. In the response JSON I have the subTopics id (selected by the user) but I do not have the subTopic name associated with the id.
I have to show the subTopic name in my table which is available in a separate object(see above JSON file). I don't know how to access the first JSON object while working with another.
My table view looks like this,
<tr ng-repeat-start="tableRow in searchCtrl.tableViewData" ng-click="tableRow.expanded = !tableRow.expanded">
<td>{{tableRow.project.name}}</td>
<td>{{tableRow.project.number}}</td>
<td>{{tableRow.project.endDate | date}}</td>
<td>{{tableRow.topicIds[0]}}</td>
<td>{{tableRow.matching.score}}</td>
</tr>
As you can see the 4th row: <td>{{tableRow.topicIds[0]}}</td> shows the id. How can I show the topicName?
Any help would be appreciable.
EDIT
In my controller this variable contains the above JSON object.
if (!self.topic) {
searchService.getTopic().then(
function (response) {
self.topic = response.data;
},
function (error) {
alert("Server is not found");
}
);
}
So, the topic variable contains the response JSON object. Maybe it will help.
You can create a function that takes an id and returns the subTopic.
$scope.getSubTopic = function(id) {
var selectedSubTopic = {};
angular.forEach(subTopics, function(subTopic) {
// loop through subTopics until a matching id is found
if (subTopic.id === id) {
selectedSubTopic = subTopic;
return;
}
});
return selectedSubTopic;
};
then you can update your fourth row to:
<td>{{getSubTopic(tableRow.topicIds[0]).name}}</td>
This assumes you have an array named subTopics.
Edit
As mentioned in my comment this will end up performing pretty slow for heavy pages and/or large datasets. You will likely want to generate a map object for the subTopics for quick access. The downside being you have to generate this each time the TopicList is modified.
function generateSubTopicMap(topics) {
var map = {};
angular.forEach(topics, function(topic) {
angular.forEach(topic.subTopics, function(subTopic) {
// use this if you want the map to reference the same data
// (i.e. updating subTopic.name will update the map at the same time)
map[subTopic.id] = subTopic;
// use this if you don't want the map to reference the same data
// map[subTopic.id] = {};
// angular.copy(subTopic, map[subTopic.id]);
// you can also add the parent id here if you need access to it
// this will modify the original object if you use the first method!
// map[subTopic.id].parentId = topic.id
});
});
return map;
}
The output looks like:
{
"4567": {
"id": "4567",
"name": "subTopic1.1",
"number": "1.1"
},
"9876": {
"id": "9876",
"name": "subTopic1.2",
"number": :1.2"
}
}
With this you would call it after every GET request and pass it the array of topics.
// where topics is the response from the GET request
$scope.subTopics = generateSubTopicMap(topics);
And finally to display you just need:
<td>{{subTopics[tableRow.topicIds[0])].name}}</td>
Edit 2
Here is a jsfiddle showing how to use the second method. All you have to do is pass the array containing your TopicList to generateSubTopicMap and it returns an object with the keys as subTopic ids and the value as the subTopic itself.
I wouldn't worry about my first solution. It isn't going to be performant inside an ng-repeat or grabbing 2nd level objects.

Facebook Graph API not returning standard JSON

I am working on an iOS app using the MonoTouch framework. I am using Visual Studio 2010 Professional SP1 with the Xamarin.iOS (v1.3.250) extension. I have been able to open a valid FacebookConnect.FBSession by using the FacebookConnect.FBLoginView with no issues but when I try to make a Graph API request using FacebookConnect.FBRequest I recieve a non-standard JSON style string. When I run following request through the Graph API Explorer:
me?fields=albums.fields(id,name,cover_photo)
I receive the following response:
{
"id": "111111111111111111",
"albums": {
"data": [
{
"id": "111111111111111111",
"name": "Some Album (#1)",
"cover_photo": "111111111111111111",
"created_time": "000-00-00T00:00:00+0000"
},
{
"id": "111111111111111111",
"name": "Some Album (#2)",
"cover_photo": "111111111111111111",
"created_time": "000-00-00T00:00:00+0000"
},
],
"paging": {
"cursors": {
"after": "xxxxxxxx=",
"before": "xxxxxxxx="
}
}
}
}
Now all of this is just fine and is what I expect to receive but when I make the same Graph API request from my app like this:
public static void GetPhotoAlbums(string _userID)
{
// _userID = "me"
mFBRequest = new FBRequest(FBSession.ActiveSession, _userID + "?fields=albums.fields(id,name,cover_photo)");
FBRequestConnection fbRequestConnection = new FBRequestConnection();
fbRequestConnection.AddRequest(mFBRequest, OnPhotoAlbumsReceived);
fbRequestConnection.Start();
}
static void OnPhotoAlbumsReceived(FBRequestConnection _connection, NSObject _result, NSError _error)
{
if (_error == null)
{
Console.WriteLine("FacebookManager.OnPhotoAlbumsReceived() - JSON: " + _result.Description);
object o = JsonConvert.DeserializeObject(_result.Description);
// ...
}
}
I receive this JSON 'like' response:
{
albums = {
data = (
{
"cover_photo" = 111111111111111111;
"created_time" = "000-00-00T00:00:00+0000";
id = 111111111111111111;
name = "Some Album (#1)";
},
{
"cover_photo" = 111111111111111111;
"created_time" = "000-00-00T00:00:00+0000";
id = 111111111111111111;
name = "Some Album (#2)";
},
);
paging = {
cursors = {
after = "xxxxxxxx=";
before = "xxxxxxxx=";
};
};
};
"id": "111111111111111111";
}
I'm not really sure how/why I'm getting a response formatted in a non-standard way but needless to say, I get Newtonsoft.Json.JsonReaderException when attempting to deserialize the data because it does not follow the standard formatting rules (ie, = instead of : to separate key/value pairs, ; instead of , to separate elements of a container, some keys having quotes while others do not, etc...)
I'm pretty new to Facebook and JSON stuff in general and am really at a loss for what is happening to the response string I receive. Any help, feedback, ideas are greatly appreciated. Thanks.
* Solution *
After a bunch of digging around it seems to be that the Graph API response is indeed JSON but it gets converted to an FBGraphObject which holds a NSMutableArray as it the data makes its way through the MonoTouch->.NET bindings so when I pulled _result.Description (equivalent to _result.ToString() it returned me the string representation of that object which happens to look a lot like JSON but is not. After finding all this out (and a lot of runtime experimentation), I was finally able to extract the data into a usable state by doing this:
static void OnPhotoAlbumsReceived(FBRequestConnection _connection, NSObject _result, NSError _error)
{
if (_error == null)
{
NSArray fieldData = (NSArray) _result.ValueForKeyPath(new NSString("albums.data.name"))
string[] names = NSArray.StringArrayFromHandle(fieldData.Handle);
// ...
}
}
Although this works for me, I have a feeling that there is a better or more robust way to get the data I requested, so if any developers out there can offer any additional tips for improving this solution, I would love to hear them.
As stated in Facebook SDK documentation Graph API:
When a request returns a non-JSON response (such as a "true" literal),
that response will be wrapped into a dictionary using this const as
the key. This only applies for very few Graph API prior to v2.1.
So you can check first if result is an NSDictionary, otherwise you can deserialize the JSON data as usual.
Below some obj-c code you can translate into C#/MonoTouch (I don't know the framework, I hope it is helpful).
NSDictionary *dict;
if ([graphResult isKindOfClass:[NSDictionary class]]) {
dict = (NSDictionary *)graphResult;
} else {
NSError *JSONError;
dict = [NSJSONSerialization JSONObjectWithData:graphResult options:NSJSONReadingAllowFragments error:&JSONError];
if (JSONError) {
NSLog(#"Facebook: JSON parse error: %#", JSONError);
// Handle error
}
}