Use $resource of AngularJS to find specific element in json Array - json

I am new to AngularJS. Trying to get specific element from a JSON array via $resource.
The structure of JSON file staffs.json is like:
[{
"id": 0,
"facility_id": [0],
"name": "Tim",
"role_id": 0
},
{
"id": 1,
"facility_id": [0],
"name": "Duncan",
"role_id": 0
},
{
"id": 2,
"facility_id": [0],
"name": "Tony",
"role_id": 1
},
{
"id": 3,
"facility_id": [0],
"name": "Parker",
"role_id": 1
},
{
"id": 4,
"facility_id": [0],
"name": "Manu",
"role_id": 2
},
{
"id": 5,
"facility_id": [0],
"name": "Ginobili",
"role_id": 2
},
{
"id": 6,
"facility_id": [0],
"name": "Tiago",
"role_id": 3
},
{
"id": 7,
"facility_id": [0],
"name": "Splitter",
"role_id": 3
}]
I am trying to get a staff whose name is "Tiago".
The code is:
var url = 'data/staffs.json';
var username = 'Tiago';
users = $resource(url);
users.get({name: username}, function(data){
alert(data.name);
});
It seems the alert() function inside the get() never gets called. However if I changed the method from users.get() to users.query(), it can get the list of the staffs. I guess this is because the data inside the JSON file is an array, so the query() which is used to get array works, while the get() does not work because it is not for array operation. Am I correct?
I am just wondering if I have to use query() get the whole array and match the elements one by one until I find the one with the same name, or there are some simpler ways to get the element I want.
Thanks

AngularJS resource has a separate query function to avoid JSONP vulnerability for arrays. You have two options:
get all and find the element in the array on the client side
add extra API endpoint for single user and fetch it by the name
I vote for option two, since you don't have to send everything over the wire and you use server (DB) to get the specific user. Server software is optimised for that.

Your best bet would by fetching data with the query() method, then using indexOf()
var url = 'data/staffs.json';
var username = 'Tiago';
users = $resource(url);
users.get({name: username}, function(data){
dataOfMyUser = data.map(function(cur) { return cur.name }).indexOf(username);
alert(dataofMyUser);
});

Related

Vuex cannot find object in object, returns undefined

I'm trying to access an object in my Vuex state winthin an action. However i cant seem to access all object keys. I can access name, but not role.
This is the object:
{
"id": 1,
"name": "Ionas Skopelitis",
"role": {
"id": 1,
"rolename": "Member",
"privileges": [
{
"id": 3,
"role_id": 1,
"name": "post"
}
]
}
}
Using this line:
const user = this.state.userData.role;
my console logs undefined
To no avail i cant get the roles and the privileges. What can i use to get an array of only the 'privileges'?
The correct form is:
const user = this.$store.state.userData.role

Accessing JSON array within JSON object in VBA Excel using VBA-JSON

I am working on VBA macros to access live data from a website through API calls. I am using VBA-JSON library for it. There are mainly two scenarios when fetching data:
Scenario #1 (we can see data is a JSON array):
{
"success": true,
"data": [
{
"id": 4,
"creator_user_id": {
"id": 162,
"name": "ASD",
"email": "email id"
},
"user_id": {
"id": 787878,
"name": "XYZ",
"email": "email id"
},
...
}
]
}
In the scenario 1 I can fetch values within data array by using For Each loop in VBA Excel through VBA-JSON library.
Scenario #2:
{
"success": true,
"data": {
"id": 123,
"name": "ABC",
"options": [
{
"id": 119,
"label": "Name1"
},
{
"id": 120,
"label": "Name2"
}
],
"mandatory_flag": false
}
}
But in 2nd scenario I can not access data within data array, because JSON data array is within JSON object. For example I want the value of id: 120 which must return Name2, thus I want to access value of label which will return Name2.
I tried many ways, but can not get it. Please anyone can tell me how this can be done in VBA Excel?
Any help appreciated.
Using the VBA-JSON library, you can access the value you want by calling:
Set Parsed = JsonConverter.ParseJson(<yourjsonstring>)
Debug.Print Parsed("data")("options")(2)("label")

React get JavaScript Object from JSON file?

The issue is that I'm trying to get a JavaScript object like the following:
[
"id" : 11,
"name" : "Peter"
"other": {
"id": 22,
"item": 534
},
"main": false
]
Since I want to get this via reactjs: I trying to do this:
http.get(API.BASE_URL + API.USER_INFO)
.accept('Application/json')
.end((err, res) => {
//console.log(x);
console.log(err);
console.log(res);
});
When I try a normal json string I get the right result, but with this javascript object I get:
Error: Parser is unable to parse the response
undefined
Has anyone come across this before? Any idea?
What you're trying to parse isn't valid JSON (as well as JavaScript) because you've written it out as an array, but still use key/value pairs as if it were an object. Try this instead:
{
"id": 11,
"name": "Peter",
"other": {
"id": 22,
"item": 534
},
"main": false
}

Parsing Different Json Objects in WP8

Please help me in parsing this Json sample as I'm not able to parse it because of the complexity of it as well as different objects inside it. I'm able to parse Json when a list of same objects & same structure but not like the one below.
[
{
"notificationBrowserHead":
{
"notificationId": 4,
"notificationType": "NEW_PRODUCT",
"creationTime": 1421933381000,
"notificationNormalUserId": 4,
"notificationViewed": false
},
"brandIdAndNameHolder":
{
"brandId": 1,
"name": "B1"
},
"brandLogo": null,
"productIdAndNameHolder":
{
"productId": 1,
"name": "JK product1"
}
},
{
"notificationBrowserHead":
{
"notificationId": 2,
"notificationType": "USER_INT_COMMENT",
"creationTime": 1421924403000,
"notificationNormalUserId": 2,
"notificationViewed": false
},
"uploadId": 22,
"uploadThumbnail": "/mediaUrl/location/thumbNail",
"uploadDescription": "upload 1 location desc",
"notificationCreator":
{
"normalUserId": 90,
"displayName": "amit"
},
"uploadRemoved": false
},
{
"notificationBrowserHead":
{
"notificationId": 1,
"notificationType": "NEW_LOCATION_VOTE",
"creationTime": 1421924403000,
"notificationNormalUserId": 1,
"notificationViewed": false
},
"locationIdAndNameHolder":
{
"locationId": 11,
"name": "Current King JK"
},
"locationLogo": null
}
]
Any help would be truly appreciated.
I presume that you receive different set of json properties when your NotificationType varies.
Solution 1:
Define all your members(the collection of all your properties that you receive for different types of notification) in a Class and use it for DeSerialization, so that the unwanted properties for your particular notification type will be null.
Solution 2:
Parser manually. Newtonsoft json documentation here
Make class "Notifications (or something)" and put inside everything you got back from json2csharp.com site, then use this framework http://www.newtonsoft.com/json to deserialize data as you download it from server and you should be able to get notificationType by Object.Notificationbrowserhead[x].notificationType or similar.

typeahead nested json object

I am new to Ember and JSON. I want to parse a JSON object that is below with typeahead library
and access nested object values by searching their keys.
I have this Json format:
return [
{
"id": 1,
"category_name": "Supermarket",
"category_description": "SUPER MARKET",
"image_url": "",
"merchants": [
{
"name": "CARREFOUR",
"id": 12,
"merchant_type_id": 1,
"merchant_type_description": "Gold",
"merchant_redeption_rate": 0.002500,
"image_url": "https://jpg",
"branches": [
{
"id": 123456,
"latitude": 37.939483,
"area": "ΑΓ. ΔΗΜΗΤΡΙΟΣ",
"zip": "12345"
},
{
"id": 4567890,
"longitude": 23.650622,
"area": "ΑΓ. ΙΩΑΝΝΗΣ ΡΕΝΤΗΣ",
"zip": "12345"
}
]
},
{
"name": "CAFCO",
"id": 13,
"merchant_type_id": 3,
"merchant_type_description": "None",
"merchant_redeption_rate": 0.002500,
"image_url": "https:.jpg",
"branches": [
{
"id": 127890,
"latitude": 38.027870,
"area": "ΠΕΡΙΣΤΕΡΙ",
"zip": "12345"
}
]
}
]
},
{
"id": 2,
"category_name": "Πολυκαταστήματα",
"category_description": "ΠΟΛΥΚΑΤΑΣΤΗΜΑ",
"image_url": "",
"merchants": [
{
"name": "AGGELOPOYLOS CHR.",
"id": 15,
"merchant_type_id": 2,
"merchant_type_description": "Silver",
"merchant_redeption_rate": 0.002500,
"image_url": "https://www.nbg.gr/greek/retail/cards/reward-programmes/gonational/PublishingImages/aggelopoulos.jpg",
"branches": [
{
"id": 234780,
"latitude": 35.366118,
"longitude": 24.479461,
"address": "ΕΘΝ. ΜΑΚΑΡΙΟΥ 9 & ΕΛ. ΒΕΝΙΖΕΛΟΥ 1",
"area": "Ν. ΦΑΛΗΡΟ",
"zip": "12345"
}
]
}
]
}
];
--------------------------Updated----------------------------
For example, i want to search using typeahead the name of merchants and when the letter we write to search matches the name of merchants it will appear the corresponding category_name and backwards.
Example -> when i keyboard the s it will appear :
Category : Supermarket,
Name: CARREFOUR
Name: CAFCO
And the same output on the dropdown of search when i keyboard the letter c.
Any help?
New Jsbin example
The simplest way (in my mind) to get this to work is to create a computed property that will contain an array of latitudes. But how do we get there?
To get to latitude, you need to go through array of merchants and then array of branches. Being that this will be across multiple elements, you are going to end up with "array of arrays" type data structure, which is annoying to deal with. So, to simplify this, we can create a simple flatten function as follows:
flatten: function(origArray){
var newArr = [];
origArray.forEach(function(el) {
el.forEach(function(eachEl){
newArr.push(eachEl);
});
});
return newArr;
},
In addition to our function above, Ember already provides us with many other useful functions that can be used on arrays (see here). One of those is mapBy(property) which transforms an array into another array only keeping the values of the property we specified.
So, to create a lats (for latitudes) property, we can just do this:
lats: function(){
var merchantsArr = this.get('model').mapBy('merchants');
merchantsArr = this.flatten(merchantsArr);
var branchesArr = merchantsArr.mapBy('branches');
branchesArr = this.flatten(branchesArr);
return branchesArr.mapBy("latitude").compact();
}.property('model')
Above, I am basically using mapBy, flatten (see above) and compact which
Returns a copy of the array with all null and undefined elements removed.
Once you have the lats property with all the necessary data, the rest is easy.
Your call to component becomes:
{{x-typeahead data=lats name='category_name' selection=myColor}}
Note lats instead of model you originally were passing into the component.
And now, to access the value of data property in the component, you do
`this.get('data')`
which you can just pass in as the source like so:
source: substringMatcher(self.get('data'))
Working solution here
Update
Updating my answer based on your updated question.
OK, so this is getting a little more complicated. You now need more than just one property (latitude) from the object. You need category_name and merchant name.
In addition to mapBy, which just grabs one property out of array, Ember also has map which lets you transform the array into pretty much anything you want to:
lats: function(){
var merchantsArr = this.get('model').map(function(thing){
var category_name = thing.category_name;
return thing.merchants.map(function(merchant){
return {
"name": merchant.name,
"category": category_name
};
});
});
merchantsArr = this.flatten(merchantsArr);
return merchantsArr;
}.property('model')
The code above looks complicated, but it's basically just returning an array of top level objects' merchants accompanied by category_name. Since this is an array of arrays, we will need to flatten it.
Then, inside the component, we need to keep in mind that we are not just passing in an array of strings, but rather we are passing in an array of objects. Therefore, we need to look through object's properties (name and category) for a match
$.each(strs, function(i, str) {
if (substrRegex.test(str.name) || substrRegex.test(str.category)) {
matches.push(str);
}
});
Lastly, to actually display both category and merchant name, you need to tell Typeahead how to do that:
templates: {
suggestion: Handlebars.compile('<p>{{name}} – {{category}}</p>')
}
Working solution here