Related
I'm looking for a way to filter this JSON and retrieve only the cost when fid > 10
Working example, the parent prop is an array:
[
{
"id": 1,
"properties": {
"parent": [
{
"fid": 10,
"cost": 100
}
]
}
},
{
"id": 2,
"properties": {
"parent": [
{
"fid": 20,
"cost": 200
}
]
}
},
{
"id": 32,
"properties": {
"parent": [
{
"fid": 30,
"cost": 300
}
]
}
}
]
JSONPath = $[*].properties.parent[?(#['fid']>10)].cost
result = [
200,
300
]
Not working example, the parent prop is now an object:
[
{
"id": 1,
"properties": {
"parent": {
"fid": 10,
"cost": 100
}
}
},
{
"id": 2,
"properties": {
"parent": {
"fid": 20,
"cost": 200
}
}
},
{
"id": 32,
"properties": {
"parent": {
"fid": 30,
"cost": 300
}
}
}
]
JSONPath = $[*].properties.parent[?(#['fid']>10)].cost
The result is No match
try this
$[?(#.properties.parent.fid>10)].properties.parent.cost
GOAL: Get the values associated with the characteristic named "ram"
Example Object/Schema:
Showcase Path: product{}.characteristics[].values[]
Product {
"characteristics": [ //1st level
{ //1st level object
"name": "ram",
"values": [ //2nd level
{"value": 2}, //to be returned in aggregation
{"value": 4} //to be returned in aggregation
]
}
]
}
Document:
{
"_index": "product",
"_type": "_doc",
"_id": "18",
"_score": 1.0,
"_source": {
"doc": {
"id": 18,
"name": "iphone_11",
"localizedName": [
{
"locale": "en-US",
"value": "iPhone 11"
}
],
"productType": null,
"shops": [
],
"characteristics": [
{
"name": "ram",
"values": [
{
"value": "2",
"localizedValues": [
]
},
{
"value": "4",
"localizedValues": [
]
}
],
"localizedName": [
{
"id": 15,
"locale": "en-US",
"value": "Ram"
}
]
}
]
}
}
}
Mappings:
{
"product": {
"mappings": {
"properties": {
"doc": {
"properties": {
"characteristics": {
"type": "nested",
"properties": {
"localizedName": {
"properties": {
"id": {
"type": "long"
},
"locale": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"values": {
"type": "nested",
"properties": {
"value": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
},
"id": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
}
Current aggregation traversal:
{
"size": 0,
"aggs": {
"characteristics": {
"nested": {
"path": "characteristics"
},
"aggs": {
"ram": {
"filter": {
"bool": {
"must": [
{
"term": {
"characteristics.name": "ram"
}
}
]
}
},
"aggs": {
"values": {
"nested": {
"path": "characteristics.values"
},
"aggs": {
"all_values": {
"terms": {
"field": "characteristics.values.value"
}
}
}
}
}
}
}
}
}
}
Response:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"characteristics": {
"meta": {},
"doc_count": 0,
"ram": {
"meta": {},
"doc_count": 0,
"values": {
"doc_count": 0,
"all_values": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
}
}
}
}
This seems to work in Elasticsearch 7.15 (based on your second sample):
{
"size": 0,
"aggs": {
"characteristics": {
"nested": {
"path": "characteristics"
},
"aggs": {
"ram": {
"filter": {
"bool": {
"must": [
{
"term": {
"characteristics.name": "ram"
}
}
]
}
},
"aggs": {
"values": {
"nested": {
"path": "characteristics.values"
},
"aggs": {
"all_values": {
"terms": {
"field": "characteristics.values.value"
}
}
}
}
}
}
}
}
}
}
It's quite convoluted though so maybe it would make sense to create an additional "attribute values" index which would have a doc for each attribute value, containing also attribute name and product id/name? Then aggregation would get way simpler.
I have an flowchart input using jquery flowchart library like so:
Flowchart
I get the data representation as this:
{
"operators": {
"0": {
"properties": {
"title": "Start",
"inputs": {},
"outputs": {
"outs": {
"label": "Output (:i)",
"multiple": true
}
},
"class": "start-operator"
},
"top": 0,
"left": 0
},
"1": {
"properties": {
"title": "End",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {},
"class": "end-operator"
},
"top": null,
"left": null
},
"37": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 0
},
"38": {
"properties": {
"title": "CHROM",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 580,
"top": 0
},
"39": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 920,
"top": 0
},
"40": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 100
},
"41": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 300,
"top": 200
},
"42": {
"properties": {
"title": "REF",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 620,
"top": 140
},
"43": {
"properties": {
"title": "POS",
"inputs": {
"ins": {
"label": "Input (:i)",
"multiple": true
}
},
"outputs": {
"output": {
"label": "Output"
}
}
},
"left": 740,
"top": 320
}
},
"links": {
"0": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 0,
"toOperator": 37,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #e53935"
},
"1": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 1,
"toOperator": 40,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #d81b60"
},
"2": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 2,
"toOperator": 41,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #8e24aa"
},
"3": {
"fromOperator": "0",
"fromConnector": "outs",
"fromSubConnector": 3,
"toOperator": 43,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #5e35b1"
},
"4": {
"fromOperator": 37,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 38,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #3949ab"
},
"5": {
"fromOperator": 40,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #546e7a"
},
"6": {
"fromOperator": 41,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 42,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #039be5"
},
"7": {
"fromOperator": 38,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 0,
"color": " #00acc1"
},
"8": {
"fromOperator": 42,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": 39,
"toConnector": "ins",
"toSubConnector": 1,
"color": " #00897b"
},
"9": {
"fromOperator": 39,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 0,
"color": " #43a047"
},
"10": {
"fromOperator": 43,
"fromConnector": "output",
"fromSubConnector": 0,
"toOperator": "1",
"toConnector": "ins",
"toSubConnector": 1,
"color": " #7cb342"
}
},
"operatorTypes": {}
}
I want to use this for filtering data in tabulator so turn this into this:
[
{
"id": 1,
"pid": null
},
{
"id": 39,
"pid": 1
},
{
"id": 38,
"pid": 39
},
{
"id": 37,
"pid": 38
},
{
"id": 42,
"pid": 39
},
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
},
{
"id": 43,
"pid": 1
}
]
Then using this lines I turned into a tree:
const idMapping = data.reduce((acc, el, i) => {
acc[el.id] = i;
return acc;
}, {});
let root;
data.forEach(el => {
// Handle the root element
if (el.pid === null) {
root = el;
return;
}
// Use our mapping to locate the parent element in our data array
const parentEl = data[idMapping[el.pid]];
// Add our current el to its parent's `children` array
parentEl.children = [...(parentEl.children || []), el];
});
Here it is as a tree:
{
"id": 1,
"pid": null,
"children": [
{
"id": 39,
"pid": 1,
"children": [
{
"id": 38,
"pid": 39,
"children": [
{
"id": 37,
"pid": 38
}
]
},
{
"id": 42,
"pid": 39,
"children": [
{
"id": 40,
"pid": 42
},
{
"id": 41,
"pid": 42
}
]
}
]
},
{
"id": 43,
"pid": 1
}
]
}
Hovewer I want to simplify this further to just nested arrays of the id's. Like this:
[
1,
[
[
39,
[
[
38,
[
37
],
],
[
42,
[
40,
41
]
]
]
],
43
]
]
Question is, how to convert from tree to nested array?
You can use recursion to do this; leaf ids are passed upward without an array wrapper while interior node ids are wrapped in an array with a second element for their children.
const tree = { "id": 1, "pid": null, "children": [ { "id": 39, "pid": 1, "children": [ { "id": 38, "pid": 39, "children": [ { "id": 37, "pid": 38 } ] }, { "id": 42, "pid": 39, "children": [ { "id": 40, "pid": 42 }, { "id": 41, "pid": 42 } ] } ] }, { "id": 43, "pid": 1 } ] };
const objTreeToArrTree = node =>
node.children
? [node.id].concat([node.children.map(objTreeToArrTree)])
: node.id
;
console.log(JSON.stringify(objTreeToArrTree(tree), null, 2));
I am trying to get specific object from a whole object below is the example
by using localStorage.getItem('shop/elasticCache/shirt');
I get below data
{"description":"Tech Shirt","configurable_options":[{"attribute_id":80,"values":[{"value_index":"5176","label":"RUST"}],"label":"Color","attribute_code":"color"},{"attribute_id":125,"values":[{"value_index":"2898","label":"Small"},{"value_index":"2901","label":"Medium"},{"value_index":"2904","label":"Large"}],"label":"Size","attribute_code":"size"}],"tsk":1594790209,"size_options":[2898,2901,2904],"regular_price":28,"final_price":null,"price":28,"color_options":[5176],"special_from_date":null,"id":250659,"category":[{"category_id":2,"name":"Default Category","position":1},{"category_id":3,"name":"Clothing","position":14985},{"category_id":30,"name":"Bottoms","position":798},{"category_id":58,"name":"Leggings","position":1},{"category_id":1130,"name":"Char Test Category","position":30}],"sku":"S155551","product_links":[{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"},{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"}
I am trying to get
{"category_id":3,"name":"Clothing","position":14985},{"category_id":30,"name":"Bottoms","position":798},{"category_id":58,"name":"Leggings","position":1},{"category_id":1130,"name":"Char Test Category","position":30}]
Is their any way it can be done ?
const {category} = JSON.parse(localStorage.getItem('shop/elasticCache/shirt');)
or
const {category } = {
"description": "Tech Shirt",
"configurable_options": [{
"attribute_id": 80,
"values": [{
"value_index": "5176",
"label": "RUST"
}],
"label": "Color",
"attribute_code": "color"
}, {
"attribute_id": 125,
"values": [{
"value_index": "2898",
"label": "Small"
}, {
"value_index": "2901",
"label": "Medium"
}, {
"value_index": "2904",
"label": "Large"
}],
"label": "Size",
"attribute_code": "size"
}],
"tsk": 1594790209,
"size_options": [2898, 2901, 2904],
"regular_price": 28,
"final_price": null,
"price": 28,
"color_options": [5176],
"special_from_date": null,
"id": 250659,
"category": [{
"category_id": 2,
"name": "Default Category",
"position": 1
}, {
"category_id": 3,
"name": "Clothing",
"position": 14985
}, {
"category_id": 30,
"name": "Bottoms",
"position": 798
}, {
"category_id": 58,
"name": "Leggings",
"position": 1
}, {
"category_id": 1130,
"name": "Char Test Category",
"position": 30
}],
"sku": "S155551",
"product_links": [{
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}, {
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}]
}
objc={"description":"Tech Shirt","configurable_options":
[{"attribute_id":80,"values":[{"value_index":"5176","label":"RUST"}],
"label":"Color","attribute_code":"color"},
{"attribute_id":125,"values":[{"value_index":"2898","label":"Small"}
,{"value_index":"2901","label":"Medium"},
{"value_index":"2904","label":"Large"}],
"label":"Size","attribute_code":"size"}],
"tsk":1594790209,"size_options":[2898,2901,2904]
,"regular_price":28,"final_price":null,"price":28,
"color_options":[5176],"special_from_date":null,"id":250659,
"category":[{"category_id":2,"name":"Default Category","position":1},
{"category_id":3,"name":"Clothing","position":14985},
{"category_id":30,"name":"Bottoms","position":798},
{"category_id":58,"name":"Leggings","position":1},
{"category_id":1130,"name":"Char Test Category","position":30}],
"sku":"S155551","product_links":
[{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"},
{"link_type":"related","linked_product_sku":null,"linked_product_type":null,"position":0,"sku":"P100031"}]
}
res = objc["category"]
res.shift()
console.log(res)
$(document).ready(function () {
var jsonObj = {
"description": "Tech Shirt",
"configurable_options": [{
"attribute_id": 80,
"values": [{
"value_index": "5176",
"label": "RUST"
}],
"label": "Color",
"attribute_code": "color"
}, {
"attribute_id": 125,
"values": [{
"value_index": "2898",
"label": "Small"
}, {
"value_index": "2901",
"label": "Medium"
}, {
"value_index": "2904",
"label": "Large"
}],
"label": "Size",
"attribute_code": "size"
}],
"tsk": 1594790209,
"size_options": [2898, 2901, 2904],
"regular_price": 28,
"final_price": null,
"price": 28,
"color_options": [5176],
"special_from_date": null,
"id": 250659,
"category": [{
"category_id": 2,
"name": "Default Category",
"position": 1
}, {
"category_id": 3,
"name": "Clothing",
"position": 14985
}, {
"category_id": 30,
"name": "Bottoms",
"position": 798
}, {
"category_id": 58,
"name": "Leggings",
"position": 1
}, {
"category_id": 1130,
"name": "Char Test Category",
"position": 30
}],
"sku": "S155551",
"product_links": [{
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}, {
"link_type": "related",
"linked_product_sku": null,
"linked_product_type": null,
"position": 0,
"sku": "P100031"
}]
};
for(var i = 1; i < jsonObj.category.length; i++){
console.log(jsonObj.category[i]);
}
});
You can iterate through the entire object and can get the required values. The above code gives the values of category from index 1.
This is an example of an api response
[
{
"id": 1,
"name": "Medicine1",
"status": true,
"location": "E1-2",
"genericName": "Medicine1 Generic name",
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 1,
"name": "Tabletas"
},
"measure": {
"id": 1,
"unit": "Gramos",
"abbreviation": "g"
},
"quantity": 25,
"percentage": null
},
{
"id": 2,
"name": "Medicine2",
"status": true,
"location": "E1-5",
"genericName": "Medicine2 Generic",
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 2,
"name": "Cremas"
},
"measure": {
"id": 1,
"unit": "Gramos",
"abbreviation": "g"
},
"quantity": 500,
"percentage": null
},
{
"id": 3,
"name": "Medicine3",
"status": true,
"location": "E1-2",
"genericName": null,
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 3,
"name": "Unguentos"
},
"measure": {
"id": 3,
"unit": "Libras",
"abbreviation": "lb"
},
"quantity": 5,
"percentage": null
},
{
"id": 4,
"name": "Medicine4",
"status": true,
"location": "E5-1",
"genericName": null,
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 1,
"name": "Tabletas"
},
"measure": {
"id": 2,
"unit": "Kilogramos",
"abbreviation": "kg"
},
"quantity": 5,
"percentage": null
},
{
"id": 5,
"name": "Medicine5",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 1,
"name": "Tabletas"
},
"measure": {
"id": 1,
"unit": "Gramos",
"abbreviation": "g"
},
"quantity": 5,
"percentage": null
},
{
"id": 6,
"name": "Medicine5",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 1,
"name": "Tabletas"
},
"measure": {
"id": 1,
"unit": "Gramos",
"abbreviation": "g"
},
"quantity": 5,
"percentage": null
},
{
"id": 7,
"name": "Medicine6",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": {
"id": null,
"name": null
},
"presentation": {
"id": 1,
"name": "Tabletas"
},
"measure": {
"id": 1,
"unit": "Gramos",
"abbreviation": "g"
},
"quantity": 5,
"percentage": null
},
{
"id": 8,
"name": "Medicine7",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": {
"id": 3,
"name": "Falcon"
},
"presentation": {
"id": 4,
"name": "Gotas"
},
"measure": {
"id": 1,
"unit": "Gramos",
"abbreviation": "g"
},
"quantity": 5,
"percentage": null
}
]
As you can see, the laboratory, percentage and genericName keys can have null value.
I need to filter this response according to a criteria that should be compared with each value
Here is the filter code
const criteria = 'some text';
fetchResource('medicines').then(medicines => {
const results = medicines.filter(medicine => {
return (
medicine.name.toLowerCase().includes(criteria) ||
medicine.genericName.toLowerCase().includes(criteria) ||
medicine.presentation.name
.toLowerCase()
.includes(criteria) ||
medicine.measure.unit.toLowerCase().includes(criteria) ||
medicine.measure.abbreviation
.toLowerCase()
.includes(criteria) ||
medicine.location.toLowerCase().includes(criteria)
);
});
const helper = makeHelper();
helper.render(results);
});
In backend, I thought about excluding the mentioned keys from the response when they do not have values. I have not tried yet but I understand that would work
I appreciate your advice on how to deal with this case on the client's side
There are other answers here that suggest using JSON.stringify to convert the entire object to a string, but that's not a great solution. It would make it impossible to search for generic, because every object has a property named genericName. There is another way to use stringify that's a bit more graceful, and that's to take advantage of the replacer callback.
For example:
const results = medicines.filter(m => {
var isMatch = false;
JSON.stringify(m, (key, value) => {
if (typeof value === "string" && value.toLowerCase().includes(criteria)) {
isMatch = true;
}
return value;
});
return isMatch;
});
results will contain only those entries from medicines that contain some value that is a string that matches the given filter. You can extend this logic to include numeric values, such as id, or exclude certain keys you're not interested in, such as abbreviation.
Here's a quick demo implementing some more advanced logic. You'll of course want to tweak it to suit your exact needs:
const medicines = [{
"id": 1,
"name": "Medicine1",
"status": true,
"location": "E1-2",
"genericName": "Medicine1 Generic name",
"laboratory": { "id": null, "name": null },
"presentation": { "id": 1, "name": "Tabletas" },
"measure": { "id": 1, "unit": "Gramos", "abbreviation": "g" },
"quantity": 25,
"percentage": null
},
{
"id": 2,
"name": "Medicine2",
"status": true,
"location": "E1-5",
"genericName": "Medicine2 Generic",
"laboratory": { "id": null, "name": null },
"presentation": { "id": 2, "name": "Cremas" },
"measure": { "id": 1, "unit": "Gramos", "abbreviation": "g" },
"quantity": 500,
"percentage": null
},
{
"id": 3,
"name": "Medicine3",
"status": true,
"location": "E1-2",
"genericName": null,
"laboratory": { "id": null, "name": null },
"presentation": { "id": 3, "name": "Unguentos" },
"measure": { "id": 3, "unit": "Libras", "abbreviation": "lb" },
"quantity": 5,
"percentage": null
},
{
"id": 4,
"name": "Medicine4",
"status": true,
"location": "E5-1",
"genericName": null,
"laboratory": { "id": null, "name": null },
"presentation": { "id": 1, "name": "Tabletas" },
"measure": { "id": 2, "unit": "Kilogramos", "abbreviation": "kg" },
"quantity": 5,
"percentage": null
},
{
"id": 5,
"name": "Medicine5",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": { "id": null, "name": null },
"presentation": { "id": 1, "name": "Tabletas" },
"measure": { "id": 1, "unit": "Gramos", "abbreviation": "g" },
"quantity": 5,
"percentage": null
},
{
"id": 6,
"name": "Medicine5",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": { "id": null, "name": null },
"presentation": { "id": 1, "name": "Tabletas" },
"measure": { "id": 1, "unit": "Gramos", "abbreviation": "g" },
"quantity": 5,
"percentage": null
},
{
"id": 7,
"name": "Medicine6",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": { "id": null, "name": null },
"presentation": { "id": 1, "name": "Tabletas" },
"measure": { "id": 1, "unit": "Gramos", "abbreviation": "g" },
"quantity": 5,
"percentage": null
},
{
"id": 8,
"name": "Medicine7",
"status": true,
"location": "E1-1",
"genericName": null,
"laboratory": { "id": 3, "name": "Falcon" },
"presentation": { "id": 4, "name": "Gotas" },
"measure": { "id": 1, "unit": "Gramos", "abbreviation": "g" },
"quantity": 5,
"percentage": null
}
];
const btn = document.getElementById("go");
const inp = document.getElementById("search");
btn.addEventListener('click', () => {
const criteria = inp.value.toLowerCase();
const results = medicines.filter(m => {
var isMatch = false;
JSON.stringify(m, (key, value) => {
// Search 'id' values
if (key === "id" && value !== null && value.toString().includes(criteria)) {
isMatch = true;
// Ignore 'abbreviation'
} else if (key !== "abbreviation") {
// Search all other string values
if (typeof value === "string" && value.toLowerCase().includes(criteria)) {
isMatch = true;
}
}
return value;
});
return isMatch;
});
console.log(results);
});
<input id="search" type="search" placeholder="filter" /><button id="go">Go</button><br>
<code>
Currently your code will error on medicine.genericName.toLowerCase() if the genericName field isn't a string. To avoid that you could try one of the following instead:
Fall back to a default:
(medicine.genericName || '').toLowerCase().includes(criteria)
Check the value first:
(medicine.genericName && medicine.genericName.toLowerCase().includes(criteria))
Its a bit tough to figure out what you're trying to do with the example, but I'm assuming you want to check if the value of multiple keys in your API response contains a substring criteria?
If that's the case, you could try something like:
fetchResource('medicines').then(medicines => {
const results = medicines.filter(medicine => {
for (var key in medicine){
if((typeof(medicine[key] == 'string' || typeof(medicine[key] == 'int') && medicine[key].toString().toLowerCase().includes(criteria)){
return true
}
else if(typeof(medicine[key]) === 'object'){
for(var subkey in medicine[key]){
if((typeof(medicine[key][subkey]) == 'string' || typeof(medicine[key][subkey]) === 'int') && medicine[key][subkey].toString().toLowerCase().includes(criteria)){
return true
}
}
}
}
return false
})
})
This is obviously much cleaner than hard coding all of the property names.
As I told before, use a forEach in your array; following a function to filter;
Use JSON.stringify so you que see all properties in row;
Apply a pattern as criteria
var yourCriteria = ""; // or any Regex
var yourArray = [];
var newArray = [];
yourArray.forEach(function(e){
if (JSON.stringify(e).toLowerCase().indexOf(yourCriteria) < 0)
newArray.push(e);
})