DART - Filter JSON Data - json

I'm trying to filter the json data. There is a field called "brand" in my json (so basically I'm trying to filter the data by brands)
This is how my json looks
{
"items": [
{
"_id": "30baa1ca-4186-4ff0-abe8-a5970e753444",
"_owner": "1d3480e5-0eda-47ef-8406-38d89bf15ded",
"_createdDate": "2022-05-09T08:47:29.137Z",
"discountedPrice": "44.97",
"_updatedDate": "2022-05-09T08:48:44.147Z",
"getDealLink": "https://amzn.to/3FqBq4O",
"brands": [
"Amazon"
],
"title": "Mellanni Extra Deep Pocket Twin XL Sheet Set ",
"amazonlogo": "wix:image://v1/1d3480_ffad681242174f799ddea471e649ef7b~mv2.png/amazon_PNG24.png#originWidth=1024&originHeight=346",
"save": "#1 Best Seller",
"link-items-all": "/items/",
"link-items-title": "/items/mellanni-extra-deep-pocket-twin-xl-sheet-set-"
},
{
"_id": "a7d3aaa8-9654-4535-b6c5-b147ff0d8eb3",
"_owner": "1d3480e5-0eda-47ef-8406-38d89bf15ded",
"_createdDate": "2022-05-08T22:35:38.398Z",
"discountedPrice": "$81.59",
"_updatedDate": "2022-05-08T22:39:52.801Z",
"getDealLink": "https://amzn.to/3ymXGLe",
"brands": [
"Amazon"
],
"originalPrice": "$199.99",
"title": "2 Pack Stadium chairs for bleachers with back support",
"amazonlogo": "wix:image://v1/1d3480_ffad681242174f799ddea471e649ef7b~mv2.png/amazon_PNG24.png#originWidth=1024&originHeight=346",
"link-items-all": "/items/",
"link-items-title": "/items/2-pack-stadium-chairs-for-bleachers-with-back-support"
},
and this is my dart code
void getAmazon() async {
var response = await http.get(Uri.parse(url));
var decodeResponse = jsonDecode(response.body);
List data = decodeResponse['items'] as List;
Iterable filteredData = data.where((element) => element['brands'][0] == 'Amazon');
print(filteredData); // returns nothing
}
it doesn't return/print anything. What am I doing wrong?

Better to use contains to check if a brand is listed. Also check if "brands" field is available for better stability.
final filteredData = data.where((element) => (element['brands'] != null ? element['brands'].contains('Amazon') : false));

In your code, you are checking if brands it's equal to Amazon, but brands is actually a List. (Or in the case you are checking on a particular index, this could change)
So ["Amazon"] ≠ Amazon.
In the code below you will now check if brands contains "Amazon".
Iterable filteredData = data.where((element) => element['brands'].contains('Amazon'));

void getAmazon() async {
var response = await http.get(Uri.parse('https://mockbin.org/bin/e123b53d-6e35-49e7-a94e-f49554a63d7e'));
var decodeResponse = jsonDecode(response.body);
List data = decodeResponse['items'] as List;
Iterable filteredData = data.where((element) => element['brands'][0] == 'Amazon');
log('ddf ${filteredData}'); // returns nothing
}
I had added third product as brand from flipkart it filter this!
you can check this url https://mockbin.org/bin/e123b53d-6e35-49e7-a94e-f49554a63d7e
Your code actually works as expected!!!
[log] ddf ({_id: 30baa1ca-4186-4ff0-abe8-a5970e753444, _owner: 1d3480e5-0eda-47ef-8406-38d89bf15ded, _createdDate: 2022-05-09T08:47:29.137Z, discountedPrice: 44.97, _updatedDate: 2022-05-09T08:48:44.147Z, getDealLink: https://amzn.to/3FqBq4O, brands: [Amazon], title: Mellanni Extra Deep Pocket Twin XL Sheet Set , amazonlogo: wix:image://v1/1d3480_ffad681242174f799ddea471e649ef7b~mv2.png/amazon_PNG24.png#originWidth=1024&originHeight=346, save: #1 Best Seller, link-items-all: /items/, link-items-title: /items/mellanni-extra-deep-pocket-twin-xl-sheet-set-}, {_id: a7d3aaa8-9654-4535-b6c5-b147ff0d8eb3, _owner: 1d3480e5-0eda-47ef-8406-38d89bf15ded, _createdDate: 2022-05-08T22:35:38.398Z, discountedPrice: $81.59, _updatedDate: 2022-05-08T22:39:52.801Z, getDealLink: https://amzn.to/3ymXGLe, brands: [Amazon], originalPrice: $199.99, title: 2 Pack Stadium chairs for bleachers with back support, amazonlogo: wix:image://v1/1d3480_ffad681242174f799ddea471e649ef7b~mv2.png/amazon_PNG24.png#originWidth=1024&originHeight=346, link-items-all: /items/, link-items-title: /items/2-pack-stadium-chairs-for-bleachers-with-back-support})

Related

How to retrive children from a single object intead of array in json-server?

I am using json-server for mock-backend to retrive children form a single object.
The parent table sentinel and the child table sensor
As you can see the sensors is an array and sentinel is an object.
I have used http://localhost:3000/sentinel?_embed=sensors but the response is not what i am expecting, because I want sensors: [{id: 1}, {id: 2}, ecc]
The official documentation shows that are two ways to retrive two tables:
_embed (include children) and _expand (include parent).
How could I achive this result?
Given that sentinel is a single object in your db.json and you can't have more than one sentinel it is not clear to me how your query is different from retrieving all sensors with sentinelId=10:
/sensors?sentinelId=10
In fact if you try this API:
/sentinel/10/sensors
it will work, because json-server rewrite the url exactly to the previous query.
If for some reason you don't want to use the sentinel id directly in the query, the other option is to use json-server as a module and define a custom route with the logic you need. Here's a basic example that exposes a /sentinel/sensors API and retrieve sentinel data along with the sensors whose sentinelId equals to the current sentinel id:
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('./db.json');
const db = router.db;
server.use(jsonServer.bodyParser);
server.get('/sentinel/sensors', (req, res) => {
const sentinel = db.get('sentinel').value();
const sensors = db
.get('sensors')
.filter({ sentinelId: sentinel.id })
.value();
res.send({ ...sentinel, sensors: sensors });
});
server.use(router);
server.listen(3001, () => {
console.log('Mock server is running on port ' + 3001);
});
That would give you a response like this:
{
"id": 10,
"name": "Sentinel",
"sensors": [
{
"id": 1,
"sentinelId": 10
},
{
"id": 2,
"sentinelId": 10
}
]
}
Here's a stackblitz

Remove duplicate object copies from array of objects

I have an array of objects that I get from an API. The property names are dynamic (meaning I don't have an extensive list of all of them). How can I get an array of all distinct objects? The contract specifies that if key is equal value is also equal. I tried to look around but I found nothing quite like this problem.
[ 20:31:28
{
'product-management': 'Product management'
},
{
'product-development': 'Product development'
},
{
'client-work': 'Client work'
},
{
'client-work': 'Client work'
},
{
'product-development': 'Product development'
},
{
'client-work': 'Client work'
},
{
'product-development': 'Product development'
}
]
Spread the array into Object.assign() to merge all objects to a single one. Since all objects properties are unique, this will leave only one key (and value) from the duplicates. Then convert to [key, value] pairs with Object.entries(), and map back to individual objects:
const data = [{"product-management":"Product management"},{"product-development":"Product development"},{"client-work":"Client work"},{"client-work":"Client work"},{"product-development":"Product development"},{"client-work":"Client work"},{"product-development":"Product development"}]
const result = Object.entries(Object.assign({}, ...data))
.map(([k, v]) => ({ [k]: v }))
console.log(result)
Going with #Bergi's suggestion, you can also convert this to a saner API while removing duplicates:
const data = [{"product-management":"Product management"},{"product-development":"Product development"},{"client-work":"Client work"},{"client-work":"Client work"},{"product-development":"Product development"},{"client-work":"Client work"},{"product-development":"Product development"}]
const result = Object.entries(Object.assign({}, ...data))
.map(([key, value]) => ({ key, value }))
console.log(result)

Jira API | Error: "Operation value must be a string" - trying to set value nested two levels deep

Trying to create a new jira ticket of specific requestType, but it is nested two levels deep. Tried few possible alterations, but no luck. Here's the code I have,
require 'jira-ruby' # https://github.com/sumoheavy/jira-ruby
options = {
:username => jira_username,
:password => jira_password,
:site => 'https://jiraurl/rest/api/2/',
:context_path => '',
:auth_type => :basic,
:read_timeout => 120
}
client = JIRA::Client.new(options)
issue = client.Issue.build
fields_options = {
"fields" =>
{
"summary" => "Test ticket creation",
"description" => "Ticket created from Ruby",
"project" => {"key" => "AwesomeProject"},
"issuetype" => {"name" => "Task"},
"priority" => {"name" => "P1"},
"customfield_23070" =>
{
"requestType" => {
"name" => "Awesome Request Type"
}
}
}
}
issue.save(fields_options)
"errors"=>{"customfield_23070"=>"Operation value must be a string"}
Also tried passing a JSON object to customfield_23070,
"customfield_23070": { "requestType": { "name": "Awesome Request Type" } }
still no luck, get the same error message.
If it helps, this is how customfield_23070 looks like in our Jira,
Does anyone know how to set requestType in this case, please? Any help is greatly appreciated!!
It seems that for custom fields with specific data types (string/number), you must pass the value as:
"customfield_1111": 1
or:
"customfield_1111": "string"
instead of:
"customfield_1111":{ "value": 1 }
or:
"customfield_1111":{ "value": "string" }
I'm not sure but you can try this possible examples:
eg.1:
"customfield_23070"=>{"name"=>"requestType","value"=>"Awesome Request Type"}
eg.2:
"customfield_23070"=>{"requestType"=>"Awesome Request Type"}
eg.3:
"customfield_23070"=>{"value"=>"Awesome Request Type"}
eg.4
"customfield_23070"=>{"name"=>"Awesome Request Type"}
for ref there are 2 methods depending upon the fields you are interacting with
have a look here '
updating-an-issue-via-the-jira-rest-apis-6848604
' for the applicable fields for update via verb operations, the other fields you can use examples as per above,
you can use both methods within the same call
{
"update": {"description": [{"set": "Description by API Update - lets do this thing"}]},
"fields": {"customfield_23310": "TESTING0909"}
}
Ok, I think I found how to do it.
You need to provide a string, and that string is the GUID of the RequestType.
In order to get that GUID. You need to run the following in a scriptrunner console:
import com.atlassian.jira.component.ComponentAccessor
def issue = ComponentAccessor.issueManager.getIssueByCurrentKey("ISSUE-400546") //Issue with the desired Request Type
def cf = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Tipo de solicitud del cliente") //Change it to the name of your request type field
issue.getCustomFieldValue(cf)
Source: https://community.atlassian.com/t5/Jira-Software-questions/how-to-set-request-type-value-in-while-create-jira-issue/qaq-p/1106696

Filtering a json array based on a list of values

I am new to typescript in angular 2 and i stuck with a situation.
I have a json array in this format
needle json
[{"empId":100,"orgId":500}
{"empId":201,"orgId":566}]
The above json is in a particular order and we need to keep that order maintained while looking for those in another json array(Haystack)
Haystack json array
[
{"empCode":21,"fname":"Ashish","Lname":"Shukla"},
{"empCode":22,"fname":"John","Lname":"Mark"},
{"empCode":21,"fname":"Vigil","Lname":"Rocker"},
{"empCode":201,"fname":"Rick","Lname":"Mandez"},
{"empCode":21,"fname":"Erik","Lname":"Francis"},
{"empCode":100,"fname":"Alex","Lname":"Mishra"},
{"empCode":21,"fname":"Feeder","Lname":"Kapoor"},
{"empCode":21,"fname":"Dan","Lname":"Rox"},
{"empCode":21,"fname":"Herb","Lname":"Deen"},
{"empCode":21,"fname":"Nate","Lname":"Diaz"},
{"empCode":21,"fname":"Nick","Lname":"Diaz"},
{"empCode":21,"fname":"Conor","Lname":"Pussy"}
]
Now i need to get those values from haystack array whose id matches in needle keeping the order maintained of the needle
{"empCode":100,"fname":"Alex","Lname":"Mishra"},
{"empCode":201,"fname":"Rick","Lname":"Mandez"}
I have achieved the solution to this problem but i guess my solution is not optimal as i am using many loops. Can some one suggest me a good solution.
PLS NOTE: Order of the employee id should be maintained in result json as of the needle json.
Thanks a lot :)
This should work
public needle: any;
public hayStack: any;
this.needle = [
{"empId": 100, "orgId": 500},
{"empId": 201, "orgId": 566}
];
this.hayStack = [
{"empCode":21,"fname":"Ashish","Lname":"Shukla"},
{"empCode":22,"fname":"John","Lname":"Mark"},
{"empCode":21,"fname":"Vigil","Lname":"Rocker"},
{"empCode":201,"fname":"Rick","Lname":"Mandez"},
{"empCode":21,"fname":"Erik","Lname":"Francis"},
{"empCode":100,"fname":"Alex","Lname":"Mishra"},
{"empCode":21,"fname":"Feeder","Lname":"Kapoor"},
{"empCode":21,"fname":"Dan","Lname":"Rox"},
{"empCode":21,"fname":"Herb","Lname":"Deen"},
{"empCode":21,"fname":"Nate","Lname":"Diaz"},
{"empCode":21,"fname":"Nick","Lname":"Diaz"},
{"empCode":21,"fname":"Conor","Lname":"Pussy"}
];
const needleEmpId = this.needle.map(item => item.empId);
const hayStackEmpCode = this.hayStack.map(item => item.empCode);
const result = hayStackEmpCode.map((id, index) => {
if (needleEmpId.indexOf(id) != -1) {
return this.hayStack[index];
}
}).sort().filter(item => (item != undefined));
console.log(result);
Result
0:{empCode: 100, fname: "Alex", Lname: "Mishra"}
1:{empCode: 201, fname: "Rick", Lname: "Mandez"}

How to count json data item ionic2

I find a new problem,
I would like to count #NAME to set array FACET[] for show #KEY
Myjson
" RESULT":{
"FACET":[
{ "#NAME" : "creator",
"#COUNT" : "20",
"FACET_VALUES":[
{
"#KEY":"Book Company1",
"#VALUE":"13"},
{
"#KEY":"Book Company1์",
"#VALUE":"10"}],
{ "#NAME" : "lang",
"#COUNT" : "70",
"FACET_VALUES":[
{
"#KEY":"tha",
"#VALUE":"33"},
{
"#KEY":"eng",
"#VALUE":"42"}
],
{ "#NAME" : "bnb",
"#COUNT" : "64",
"FACET_VALUES":[
{
.
.
.
]
.
optionsFn(): void {
this.http.get("my_url")
.subscribe(data =>{
this.date=data.json().RESULT.FACET; //get #NAME
},error=>{
err => console.error(err),
() => console.log('getRepos completed')
);
console.log(this.date);
console.log(this.date);
this.goToapply()
}
goToapply(){
this.http.get("my_url")
.subscribe(data =>{
this.foundRepos=data.json().RESULT.FACET[0,1,2,3.4......].FACET_VALUES; ///get #KEY
},error=>{
console.log(error);
} );
}
..
<ion-label>Filterr</ion-label>
<ion-select [(ngModel)]="refine" (ionChange)="optionsFn();">
<ion-option value="..." *ngFor="let item of date">{{item["#NAME"]}},({{item["#COUNT"]}})</ion-option>
</ion-select>
<ion-list>
<ion-item *ngFor="let item of foundRepos" (click)="itemClicked($event,item)">
<h3> {{ item[#KEY"] }}</h3>
</ion-item>
</ion-list>
This value="..." I want to keep it to string for to use, but zi have know idea.
example : count #NAME = 3 (creator,lang,bnb) ,and get value="..." = 0,1,2 (0==creator ,1==lang ,2==bnb)
When I select lang I get 1 , I use this to FACET[1].FACET_VALUES , So that I get #KEY
Sorry to write wrong. My english isn't very good.
Ok. there's just a tip that I would like to point out to you. You shoud get a bit better with words. Not the English language in particular but more about explaining your current result and your desired result. I believe this will force you into learning english at a much faster pace than you're currently doing. (coming from a non-native speaker)
"I would like to count#NAME to set array FACET[] for show #KEY"
So, with the returned JSON we can do a couple of things, which do not get quite clear from immediately looking at your question (did a +1 since I don't believe it's of bad quality or isn't a good question).
So there are 3 things I should cover in my post
Counting the amount that NAME occurs
Setting an array for the FACET
Showing the KEY per FACET which seems to be the end goal.
Ok
Counting the amount that NAME occurs
So you basically already got this answer. You submitted this code
this.http.get("my_url")
.subscribe(data =>{
this.date=data.json().RESULT.FACET; //get #NAME
});
Which means you already have access to the FACET array. Counting the amount that NAME occurs can be done either by creating a for loop and checking if the name is not undefined (thus incrementing an int) or counting on the fact that NAME is always defined, thus just calling this.date.size() (if this.date is set correctly of course)
get an array for the FACET
this, you're already doing by assiging the this.date = data.json().RESULT.FACET. Your this.date now contains an array holding your FACET objects. Just see it like this: JSON (with comments which is not possible in JSON but just for demonstration purposes) =
{ FACET: // declare the main object, called FACET
[ // declaring the FACET as an Array ([] is for creating a list)
{id: 2} //initializing a child of the FACET array
,{id: 3} //initializing the second FACET child.
]
}
So, this pseudo (not realistic) JSON holds 2 objects, having id = 2 and id = 3
Ok, now you should understand a bit of JSON, let's take a look at how your code looks (taking a Businnes with multiple offices and multiple employees per office into account)
{
OFFICES" : [
{
"id" : "1",
"location" : "New York",
"employees" : [
{"id" : "1", "fullName" : "Jon Skeet"},
{"id" : "2", "fullName" : "Random Stranger"}
]
},
{
"id" : "2",
"location" : "Amsterdam",
"employees" : [
{"id" : "1", "fullName" : "Ivaro18"},
{"id" : "2", "fullName" : "Some-Random Stranger"}
]
}
]
}
This code is basically the same as your code. And the question your asking now is, taking the code from my answer, how to get all the id's or names of all the employees. (get all names of keys of facet objects)
Now let's show you in typescript
someFunction() {
this.http.get('someUrl').map(response => {
console.log(JSON.stringify(response.json())); // check what you actually retrieve
let decoded = response.json();
for(let office of decoded.OFFICE) {
console.log(office.location);
for(let employee of office.employees) {
console.log(employee.fullName);
}
}
});
}
Expected output of this program
> New York
> Jon Skeet
> Random Stranger
> Amsterdam
> Ivaro18
> Some-Random Stranger
I think this pseudo code will get you to think a bit out-of-the-box and find the answer to your question. If you can't elaborate more on what you want as output I will be glad to help you at any time (even weekends) just comment and I'll respond when I have the time!
#Ivaro18 thanks for your answers.
I want to counting the amount that #NAME
for setting an array for the FACET
and showing the KEY per FACET[] which seems to be the end goal.
Yes, you totally know what I meant.
But i want output is every #KEY of that FACET[]
Example :
<ion-select [(ngModel)]="refine" (ionChange)="optionsFn();">
<ion-option value="..." *ngFor="let item of date">{{item["#NAME"]}},({{item["#COUNT"]}})</ion-option>
</ion-select>
<ion-list>
<ion-item *ngFor="let item of foundRepos" (click)="itemClicked($event,item)">
<h3> {{ item[#KEY"] }}</h3>
</ion-item>
</ion-list>
.
optionsFn(): void {
this.http.get("my_url")
.subscribe(data =>{
this.date=data.json().RESULT.FACET; //get #NAME
},error=>{
err => console.error(err),
() => console.log('getRepos completed')
);
console.log(this.date);
console.log(this.date);
this.goToapply()
}
goToapply(){
this.http.get("my_url")
.subscribe(data =>{
this.foundRepos=data.json().RESULT.FACET[0,1,2,3.4......].FACET_VALUES; ///get #KEY
},error=>{
console.log(error);
} );
}
from above ion-select is show creator , lang and bnb ,I want to If When I select lang ion-option value="..."
to keep number of "#NAME"
example counting amount of #NAME is 3 and
when I select creator is ion-option value="..." << is 0
when I select lang is ion-option value="..." << is 1
when I select bnb is ion-option value="..." << is 2
and If i get value ,I take it to goToapply() for set FACET[]
example I select bnb I get value =2 and console.log this.refine
is show 2
take it(2) to let p = this.refine , so that p = 2
take p to this.foundRepos=data.json().RESULT.FACET[p].FACET_VALUES; for show #KEY in ion-list
When I select lang output is
> tha
> eng