Recursively get the 'id' keys of a nested object in Javascript - javascript

I have a nested object which can be of any depth
[
{
"id": "3",
"user_id": "1479",
"folder_id": "2",
"is_folder": true,
"folder_name": "folder 3",
"unique_filename": null,
"original_filename": null,
"file_extension": null,
"content_type": null,
"file_size": null,
"description": "People",
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T09:34:48.546+02:00",
"created_at": "2022-11-21T09:34:48.546+02:00",
"updated_at": "2022-11-21T09:34:48.546+02:00",
"children": [
{
"id": "36",
"user_id": "1479",
"folder_id": "3",
"is_folder": true,
"folder_name": "folder 4",
"unique_filename": null,
"original_filename": null,
"file_extension": null,
"content_type": null,
"file_size": null,
"description": "People",
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T21:33:48.767+02:00",
"created_at": "2022-11-21T21:33:48.767+02:00",
"updated_at": "2022-11-21T21:33:48.767+02:00",
"children": [
{
"id": "37",
"user_id": "1479",
"folder_id": "36",
"is_folder": true,
"folder_name": "folder 37",
"unique_filename": null,
"original_filename": null,
"file_extension": null,
"content_type": null,
"file_size": null,
"description": "People",
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T21:38:30.690+02:00",
"created_at": "2022-11-21T21:38:30.690+02:00",
"updated_at": "2022-11-21T21:38:30.690+02:00",
"children": []
}
]
},
{
"id": "42",
"user_id": "1479",
"folder_id": "3",
"is_folder": true,
"folder_name": "folder 41",
"unique_filename": null,
"original_filename": null,
"file_extension": null,
"content_type": null,
"file_size": null,
"description": "People",
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T23:38:31.935+02:00",
"created_at": "2022-11-21T23:38:31.935+02:00",
"updated_at": "2022-11-21T23:38:31.935+02:00",
"children": []
}
]
},
{
"id": "5",
"user_id": "1479",
"folder_id": null,
"is_folder": false,
"folder_name": null,
"unique_filename": "drives/users/user_drive_1479/YTHGg4dnzn8O5a4DGHbntsrKhY2n4ycc3hZG5j7YxdIb5yEka9iToJDi9WxQPe4taSjLP53b1s01mctIy69o7m6L92.c",
"original_filename": "sample3.c",
"file_extension": "c",
"content_type": "text/x-c",
"file_size": "126",
"description": null,
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T09:37:48.766+02:00",
"created_at": "2022-11-21T09:37:48.767+02:00",
"updated_at": "2022-11-21T09:37:48.767+02:00",
"children": []
},
{
"id": "7",
"user_id": "1479",
"folder_id": null,
"is_folder": false,
"folder_name": null,
"unique_filename": "drives/users/user_drive_1479/FSix4WZx0s9ey89x3foLxmaC1wCHTSw1HQi8fDxQ32bYQyKmyPJBcgeI33KOrdPfAcOChvkBnIBizj5IQbggeprCpz.cpp",
"original_filename": "sample1.cpp",
"file_extension": "cpp",
"content_type": "text/x-c",
"file_size": "94",
"description": null,
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T09:37:52.324+02:00",
"created_at": "2022-11-21T09:37:52.324+02:00",
"updated_at": "2022-11-21T09:37:52.324+02:00",
"children": []
},
{
"id": "37",
"user_id": "1479",
"folder_id": "36",
"is_folder": true,
"folder_name": "folder 37",
"unique_filename": null,
"original_filename": null,
"file_extension": null,
"content_type": null,
"file_size": null,
"description": "People",
"visible": false,
"status": 0,
"deleted_at": null,
"last_access": "2022-11-21T21:38:30.690+02:00",
"created_at": "2022-11-21T21:38:30.690+02:00",
"updated_at": "2022-11-21T21:38:30.690+02:00",
"children": []
}
]
I need to get the value of all the id keys
from the array of objects above the expected outcome would be
[3,36,37,42,5,7,37]
the code I have tried is shown below
if (data.children) {
console.log(data.id)
data.children.forEach(item => {
this.getObject(item)
})
} else {
console.log(data.id)
}
the data variable being the array of objects above
I get undefined as a result.
your assistance would be much appreciated

Using a recursive technique can cause a stack overflow if the node treelist is too numerous. An iterative approach is safer:
TS Playground
type NodeWithChildren<T> = T & { children?: T[] };
function collectNodeValues <
K extends string,
T extends NodeWithChildren<Record<K, unknown>>,
>(nodeList: readonly T[], targetProperty: K): T[K][] {
const stack: T[] = [...nodeList];
const values: T[K][] = [];
while (stack.length > 0) {
const node = stack.shift()!;
values.push(node[targetProperty]);
if (!Array.isArray(node.children)) continue;
stack.unshift(...node.children);
}
return values;
}
const input = [{"id":"3","user_id":"1479","folder_id":"2","is_folder":true,"folder_name":"folder 3","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T09:34:48.546+02:00","created_at":"2022-11-21T09:34:48.546+02:00","updated_at":"2022-11-21T09:34:48.546+02:00","children":[{"id":"36","user_id":"1479","folder_id":"3","is_folder":true,"folder_name":"folder 4","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T21:33:48.767+02:00","created_at":"2022-11-21T21:33:48.767+02:00","updated_at":"2022-11-21T21:33:48.767+02:00","children":[{"id":"37","user_id":"1479","folder_id":"36","is_folder":true,"folder_name":"folder 37","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T21:38:30.690+02:00","created_at":"2022-11-21T21:38:30.690+02:00","updated_at":"2022-11-21T21:38:30.690+02:00","children":[]}]},{"id":"42","user_id":"1479","folder_id":"3","is_folder":true,"folder_name":"folder 41","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T23:38:31.935+02:00","created_at":"2022-11-21T23:38:31.935+02:00","updated_at":"2022-11-21T23:38:31.935+02:00","children":[]}]},{"id":"5","user_id":"1479","folder_id":null,"is_folder":false,"folder_name":null,"unique_filename":"drives/users/user_drive_1479/YTHGg4dnzn8O5a4DGHbntsrKhY2n4ycc3hZG5j7YxdIb5yEka9iToJDi9WxQPe4taSjLP53b1s01mctIy69o7m6L92.c","original_filename":"sample3.c","file_extension":"c","content_type":"text/x-c","file_size":"126","description":null,"visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T09:37:48.766+02:00","created_at":"2022-11-21T09:37:48.767+02:00","updated_at":"2022-11-21T09:37:48.767+02:00","children":[]},{"id":"7","user_id":"1479","folder_id":null,"is_folder":false,"folder_name":null,"unique_filename":"drives/users/user_drive_1479/FSix4WZx0s9ey89x3foLxmaC1wCHTSw1HQi8fDxQ32bYQyKmyPJBcgeI33KOrdPfAcOChvkBnIBizj5IQbggeprCpz.cpp","original_filename":"sample1.cpp","file_extension":"cpp","content_type":"text/x-c","file_size":"94","description":null,"visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T09:37:52.324+02:00","created_at":"2022-11-21T09:37:52.324+02:00","updated_at":"2022-11-21T09:37:52.324+02:00","children":[]},{"id":"37","user_id":"1479","folder_id":"36","is_folder":true,"folder_name":"folder 37","unique_filename":null,"original_filename":null,"file_extension":null,"content_type":null,"file_size":null,"description":"People","visible":false,"status":0,"deleted_at":null,"last_access":"2022-11-21T21:38:30.690+02:00","created_at":"2022-11-21T21:38:30.690+02:00","updated_at":"2022-11-21T21:38:30.690+02:00","children":[]}];
const ids = collectNodeValues(input, 'id');
console.log(ids); // ["3", "36", "37", "42", "5", "7", "37"]
Compiled JS from the TS Playground:
"use strict";
function collectNodeValues(nodeList, targetProperty) {
const stack = [...nodeList];
const values = [];
while (stack.length > 0) {
const node = stack.shift();
values.push(node[targetProperty]);
if (!Array.isArray(node.children))
continue;
stack.unshift(...node.children);
}
return values;
}
const input = [{ "id": "3", "user_id": "1479", "folder_id": "2", "is_folder": true, "folder_name": "folder 3", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T09:34:48.546+02:00", "created_at": "2022-11-21T09:34:48.546+02:00", "updated_at": "2022-11-21T09:34:48.546+02:00", "children": [{ "id": "36", "user_id": "1479", "folder_id": "3", "is_folder": true, "folder_name": "folder 4", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T21:33:48.767+02:00", "created_at": "2022-11-21T21:33:48.767+02:00", "updated_at": "2022-11-21T21:33:48.767+02:00", "children": [{ "id": "37", "user_id": "1479", "folder_id": "36", "is_folder": true, "folder_name": "folder 37", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T21:38:30.690+02:00", "created_at": "2022-11-21T21:38:30.690+02:00", "updated_at": "2022-11-21T21:38:30.690+02:00", "children": [] }] }, { "id": "42", "user_id": "1479", "folder_id": "3", "is_folder": true, "folder_name": "folder 41", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T23:38:31.935+02:00", "created_at": "2022-11-21T23:38:31.935+02:00", "updated_at": "2022-11-21T23:38:31.935+02:00", "children": [] }] }, { "id": "5", "user_id": "1479", "folder_id": null, "is_folder": false, "folder_name": null, "unique_filename": "drives/users/user_drive_1479/YTHGg4dnzn8O5a4DGHbntsrKhY2n4ycc3hZG5j7YxdIb5yEka9iToJDi9WxQPe4taSjLP53b1s01mctIy69o7m6L92.c", "original_filename": "sample3.c", "file_extension": "c", "content_type": "text/x-c", "file_size": "126", "description": null, "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T09:37:48.766+02:00", "created_at": "2022-11-21T09:37:48.767+02:00", "updated_at": "2022-11-21T09:37:48.767+02:00", "children": [] }, { "id": "7", "user_id": "1479", "folder_id": null, "is_folder": false, "folder_name": null, "unique_filename": "drives/users/user_drive_1479/FSix4WZx0s9ey89x3foLxmaC1wCHTSw1HQi8fDxQ32bYQyKmyPJBcgeI33KOrdPfAcOChvkBnIBizj5IQbggeprCpz.cpp", "original_filename": "sample1.cpp", "file_extension": "cpp", "content_type": "text/x-c", "file_size": "94", "description": null, "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T09:37:52.324+02:00", "created_at": "2022-11-21T09:37:52.324+02:00", "updated_at": "2022-11-21T09:37:52.324+02:00", "children": [] }, { "id": "37", "user_id": "1479", "folder_id": "36", "is_folder": true, "folder_name": "folder 37", "unique_filename": null, "original_filename": null, "file_extension": null, "content_type": null, "file_size": null, "description": "People", "visible": false, "status": 0, "deleted_at": null, "last_access": "2022-11-21T21:38:30.690+02:00", "created_at": "2022-11-21T21:38:30.690+02:00", "updated_at": "2022-11-21T21:38:30.690+02:00", "children": [] }];
const ids = collectNodeValues(input, 'id');
console.log(ids); // ["3", "36", "37", "42", "5", "7", "37"]

Considering that the schema of the object is like what you have written, first you can define a variable to store the id list.
let idList = [];
Then write a recursive function to get Ids like this:
function getId(obj){
obj?.map(item =>{
if(item?.id){
idList.push(item.id);
}
if(item?.children && item.children.length){
getId(item.children);
}
})
}
Next call the function and pass the object that you want, to fill idList.

Related

How to get post categories from an object in array

Im trying to filter posts by categories from this array
Array [
Object {
"category": 1,
"content": "For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
[Link1](https://cso-web.herokuapp.com)",
"content_preview": null,
"coverImageSubtitle": null,
"coverImageTitle": null,
"created_at": "2021-05-13T18:34:17.260Z",
"custom_link": null,
"gallery": Array [],
"id": 1,
"isDeleted": null,
"locale": "sq",
"localizations": Array [],
"pages": Array [
Object {
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:19:15.101Z",
"id": 18,
"isActive": true,
"locale": "sq",
"name": "Member Listing",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "member-listing",
"template": "member-listing",
"updated_at": "2021-09-28T09:29:56.383Z",
},
Object {
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:33:28.500Z",
"id": 22,
"isActive": true,
"locale": "sq",
"name": "Evaluation Process / AL",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "evaluation-process",
"template": "join-now",
"updated_at": "2021-05-19T21:33:29.331Z",
},
],
"post_categories": Array [
Object {
"created_at": "2021-05-20T15:54:36.949Z",
"id": 1,
"locale": "sq",
"name": "Lajmet",
"published_at": "2021-05-20T15:54:45.222Z",
"updated_at": "2021-05-20T15:54:46.179Z",
},
],
"published_at": "2021-05-13T18:34:17.260Z",
"slider": Array [
Object {
"fixed": null,
"id": 6,
"image": Array [
Object {
"alternativeText": "",
"caption": "",
"created_at": "2021-05-13T18:34:10.259Z",
"ext": ".svg",
"formats": null,
"hash": "feature_image_297dbc6cd8",
"height": 450,
"id": 11,
"mime": "image/svg+xml",
"name": "feature-image.svg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"size": 54.94,
"updated_at": "2021-05-13T18:34:10.522Z",
"url": "/uploads/feature_image_297dbc6cd8.svg",
"width": 600,
},
],
"parallax": null,
},
],
"sort": null,
"subTitle": null,
"thumbnail": null,
"title": "Our Vision, Mission and Guiding Principles",
"updated_at": "2021-06-22T09:27:39.155Z",
},
Object {
"category": null,
"content": "It is a quick and easy way for self-evaluating an organization in relation to the Global Standard for CSO Accountability, aiming at identifying strengths and areas for improvement.
<img src=\"/uploads/logo_2_319de9613c.jpeg\" style=\"width: 100px; height: 150px\" />
Legacy giving requires thought, lots of time and technical skills. So how do you make it as easy as possible for your donors to consider pledging a gift in a will? What decision science nudges can you use to help them along the decision-making process?
In this session you will learn the fundamentals of decision science, how people make decisions and which nudges you can use in your gifts in wills marketing to transform your appeals and secure pledges.
Learning Outcomes
1) Understand how designing legacy marketing differs from other fundraising materials
2) Learn how to leverage decision science nudges to inspire donors to consider leaving a gift in a will
3) How to write impactful legacy marketing",
"content_preview": null,
"coverImageSubtitle": null,
"coverImageTitle": null,
"created_at": "2021-05-25T21:21:03.979Z",
"custom_link": null,
"gallery": Array [],
"id": 8,
"isDeleted": null,
"locale": "sq",
"localizations": Array [],
"pages": Array [],
"post_categories": Array [],
"published_at": "2021-05-25T21:22:12.934Z",
"slider": Array [],
"sort": null,
"subTitle": "Përparimi i karrierës suaj në një botë post pandemike",
"thumbnail": null,
"title": "Publikim CSO",
"updated_at": "2021-05-25T21:22:13.300Z",
},
Object {
"category": 2,
"content": "For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
- [CSO Report 2020-2021](/)
- [CSO Report 2020-2021](/)",
"content_preview": null,
"coverImageSubtitle": "adfasdf asdf asdf asdfsdf asdf ahsfahs dfhsdhha hhhahsd fhasd fhas dfhsahdf ahsdf ashdf hasdhf has dfh asdfhashdf. h sda fashdf hasd fhashd f ashdf hashdf ",
"coverImageTitle": "Learn everything About CSO",
"created_at": "2021-05-15T08:55:42.292Z",
"custom_link": null,
"gallery": Array [],
"id": 2,
"isDeleted": null,
"locale": "sq",
"localizations": Array [],
"pages": Array [],
"post_categories": Array [],
"published_at": "2021-05-15T08:55:42.292Z",
"slider": Array [
Object {
"fixed": true,
"id": 7,
"image": Array [
Object {
"alternativeText": "",
"caption": "",
"created_at": "2021-05-13T18:34:10.259Z",
"ext": ".svg",
"formats": null,
"hash": "feature_image_297dbc6cd8",
"height": 450,
"id": 11,
"mime": "image/svg+xml",
"name": "feature-image.svg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"size": 54.94,
"updated_at": "2021-05-13T18:34:10.522Z",
"url": "/uploads/feature_image_297dbc6cd8.svg",
"width": 600,
},
],
"parallax": null,
},
],
"sort": null,
"subTitle": "subtitle goes here",
"thumbnail": null,
"title": "Our Vision, Mission and Guiding Principles",
"updated_at": "2021-06-22T09:27:13.855Z",
},
Object {
"category": null,
"content": "",
"content_preview": "A jeni gati për t`u bërë anëtar i Kodit? <br/>
Testoni Standardet aktuale të organizatës tuaj [këtu](/evaluation).",
"coverImageSubtitle": null,
"coverImageTitle": null,
"created_at": "2021-07-30T15:37:09.909Z",
"custom_link": "/join-now",
"gallery": Array [],
"id": 58,
"isDeleted": null,
"locale": "sq",
"localizations": Array [
Object {
"id": 61,
"locale": "en",
"published_at": "2021-09-06T08:12:34.668Z",
},
],
"pages": Array [
Object {
"commitments": null,
"content_sub_menu": 2,
"created_at": "2021-05-19T13:17:54.278Z",
"id": 10,
"isActive": true,
"locale": "sq",
"name": "Rreth Kodit",
"showOnFooterMenu": null,
"showOnMainMenu": true,
"slug": "about",
"template": "about",
"updated_at": "2021-07-28T09:43:03.711Z",
},
],
"post_categories": Array [],
"published_at": "2021-07-30T15:37:25.717Z",
"slider": Array [
Object {
"fixed": false,
"id": 99,
"image": Array [
Object {
"alternativeText": "",
"caption": "",
"created_at": "2021-06-22T11:21:15.147Z",
"ext": ".1&auto=format&fit=crop&w=1350&q=80",
"formats": Object {
"large": Object {
"ext": ".1&auto=format&fit=crop&w=1350&q=80",
"hash": "large_photo_1524178232363_1fb2b075b655_ixid_Mnwx_Mj_A3f_DB_8_M_Hxwa_G90by1w_Y_Wdlf_Hx8f_G_Vuf_DB_8f_Hx8_and_ixlib_rb_1_2_df5889d144",
"height": 667,
"mime": "image/jpeg",
"name": "large_https://images.unsplash.com/photo-1524178232363-1fb2b075b655?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80",
"path": null,
"size": 93.66,
"url": "/uploads/large_photo_1524178232363_1fb2b075b655_ixid_Mnwx_Mj_A3f_DB_8_M_Hxwa_G90by1w_Y_Wdlf_Hx8f_G_Vuf_DB_8f_Hx8_and_ixlib_rb_1_2_df5889d144.1&auto=format&fit=crop&w=1350&q=80",
"width": 1000,
},
"medium": Object {
"ext": ".1&auto=format&fit=crop&w=1350&q=80",
"hash": "medium_photo_1524178232363_1fb2b075b655_ixid_Mnwx_Mj_A3f_DB_8_M_Hxwa_G90by1w_Y_Wdlf_Hx8f_G_Vuf_DB_8f_Hx8_and_ixlib_rb_1_2_df5889d144",
"height": 500,
"mime": "image/jpeg",
"name": "medium_https://images.unsplash.com/photo-1524178232363-1fb2b075b655?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80",
"path": null,
"size": 59.18,
"url": "/uploads/medium_photo_1524178232...(truncated to the first 10000 characters)
How can i go inside post_categories that i haven't figured out.
Here is the code I've done so far :
const [results, setResults] = useState([]);
const [errorMessage, setErrorMessage] = useState('');
const [category, setCategory] = useState(null);
const [filteredData, setFilteredData] = useState([]);
const filteredResults = useMemo(() => results.filter(result => category === null || result.post_categories[0].id === category), [results, category]);
const toggleFilter = cat => {
setCategory(c => cat === c ? null : cat);
setResults(results)
}
This shows an undefined is not an object error for result.post_categories[0].id
How can i access that id, inside post_categories so i can filter the results afterwards?
Right now in front page it shows all the posts. After a button is clicked the toggleFilter function is triggered and it should show only the posts with that category.
From the first array after aplying the filter the desired output should go to this array :
Array [
Object {
"category": 1,
"content": "For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.
[Link1](https://cso-web.herokuapp.com)",
"content_preview": null,
"coverImageSubtitle": null,
"coverImageTitle": null,
"created_at": "2021-05-13T18:34:17.260Z",
"custom_link": null,
"gallery": Array [],
"id": 1,
"isDeleted": null,
"locale": "sq",
"localizations": Array [],
"pages": Array [
Object {
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:19:15.101Z",
"id": 18,
"isActive": true,
"locale": "sq",
"name": "Member Listing",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "member-listing",
"template": "member-listing",
"updated_at": "2021-09-28T09:29:56.383Z",
},
Object {
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:33:28.500Z",
"id": 22,
"isActive": true,
"locale": "sq",
"name": "Evaluation Process / AL",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "evaluation-process",
"template": "join-now",
"updated_at": "2021-05-19T21:33:29.331Z",
},
],
"post_categories": Array [
Object {
"created_at": "2021-05-20T15:54:36.949Z",
"id": 1,
"locale": "sq",
"name": "Lajmet",
"published_at": "2021-05-20T15:54:45.222Z",
"updated_at": "2021-05-20T15:54:46.179Z",
},
],
"published_at": "2021-05-13T18:34:17.260Z",
"slider": Array [
Object {
"fixed": null,
"id": 6,
"image": Array [
Object {
"alternativeText": "",
"caption": "",
"created_at": "2021-05-13T18:34:10.259Z",
"ext": ".svg",
"formats": null,
"hash": "feature_image_297dbc6cd8",
"height": 450,
"id": 11,
"mime": "image/svg+xml",
"name": "feature-image.svg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"size": 54.94,
"updated_at": "2021-05-13T18:34:10.522Z",
"url": "/uploads/feature_image_297dbc6cd8.svg",
"width": 600,
},
],
"parallax": null,
},
],
"sort": null,
"subTitle": null,
"thumbnail": null,
"title": "Our Vision, Mission and Guiding Principles",
"updated_at": "2021-06-22T09:27:39.155Z",
},
Object {
"category": 2,
"content": "test",
"content_preview": null,
"coverImageSubtitle": null,
"coverImageTitle": null,
"created_at": "2021-05-13T18:34:17.260Z",
"custom_link": null,
"gallery": Array [],
"id": 1,
"isDeleted": null,
"locale": "sq",
"localizations": Array [],
"pages": Array [
Object {
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:19:15.101Z",
"id": 18,
"isActive": true,
"locale": "sq",
"name": "Member Listing",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "member-listing",
"template": "member-listing",
"updated_at": "2021-09-28T09:29:56.383Z",
},
Object {
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:33:28.500Z",
"id": 22,
"isActive": true,
"locale": "sq",
"name": "Evaluation Process / AL",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "evaluation-process",
"template": "join-now",
"updated_at": "2021-05-19T21:33:29.331Z",
},
],
"post_categories": Array [
Object {
"created_at": "2021-05-20T15:54:36.949Z",
"id": 1,
"locale": "sq",
"name": "Lajmet",
"published_at": "2021-05-20T15:54:45.222Z",
"updated_at": "2021-05-20T15:54:46.179Z",
},
],
"published_at": "2021-05-13T18:34:17.260Z",
"slider": Array [
Object {
"fixed": null,
"id": 6,
"image": Array [
Object {
"alternativeText": "",
"caption": "",
"created_at": "2021-05-13T18:34:10.259Z",
"ext": ".svg",
"formats": null,
"hash": "feature_image_297dbc6cd8",
"height": 450,
"id": 11,
"mime": "image/svg+xml",
"name": "feature-image.svg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"size": 54.94,
"updated_at": "2021-05-13T18:34:10.522Z",
"url": "/uploads/feature_image_297dbc6cd8.svg",
"width": 600,
},
],
"parallax": null,
},
],
"sort": null,
"subTitle": null,
"thumbnail": null,
"title": "Our Vision, Mission and Guiding Principles",
"updated_at": "2021-06-22T09:27:39.155Z",
},
Here is the button that should filter the results :
<Button shadowless style={styles.buttonStyle} onPress={() => { toggleFilter(1) }} >
You are getting the undefined error because for few of the cases the post_categories array is empty and if u try accessing the 0th element it will throw an error. So add a null check for the array length and for id something like below
const arr = [
{
"category": 1,
"content": "For 50 years, AFP has been the standard-bearer for professionalism in fundraising. Learn more about AFP, its activities and people, and how you can be involved.",
"content_preview": null,
"coverImageSubtitle": null,
"coverImageTitle": null,
"created_at": "2021-05-13T18:34:17.260Z",
"custom_link": null,
"gallery": [],
"id": 1,
"isDeleted": null,
"locale": "sq",
"localizations": [],
"pages": [
{
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:19:15.101Z",
"id": 18,
"isActive": true,
"locale": "sq",
"name": "Member Listing",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "member-listing",
"template": "member-listing",
"updated_at": "2021-09-28T09:29:56.383Z",
},
{
"commitments": null,
"content_sub_menu": null,
"created_at": "2021-05-19T21:33:28.500Z",
"id": 22,
"isActive": true,
"locale": "sq",
"name": "Evaluation Process / AL",
"showOnFooterMenu": null,
"showOnMainMenu": null,
"slug": "evaluation-process",
"template": "join-now",
"updated_at": "2021-05-19T21:33:29.331Z",
},
],
"post_categories": [
{
"created_at": "2021-05-20T15:54:36.949Z",
"id": 1,
"locale": "sq",
"name": "Lajmet",
"published_at": "2021-05-20T15:54:45.222Z",
"updated_at": "2021-05-20T15:54:46.179Z",
},
{
"created_at": "2021-05-20T15:54:36.949Z",
"id": 2,
"locale": "sq",
"name": "Lajmet",
"published_at": "2021-05-20T15:54:45.222Z",
"updated_at": "2021-05-20T15:54:46.179Z",
},
],
"published_at": "2021-05-13T18:34:17.260Z",
"slider": [
{
"fixed": null,
"id": 6,
"image": [
{
"alternativeText": "",
"caption": "",
"created_at": "2021-05-13T18:34:10.259Z",
"ext": ".svg",
"formats": null,
"hash": "feature_image_297dbc6cd8",
"height": 450,
"id": 11,
"mime": "image/svg+xml",
"name": "feature-image.svg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"size": 54.94,
"updated_at": "2021-05-13T18:34:10.522Z",
"url": "/uploads/feature_image_297dbc6cd8.svg",
"width": 600,
},
],
"parallax": null,
},
],
"sort": null,
"subTitle": null,
"thumbnail": null,
"title": "Our Vision, Mission and Guiding Principles",
"updated_at": "2021-06-22T09:27:39.155Z",
}]
console.log(arr.filter(el => el.post_categories.length > 0 && el.id === el.post_categories[0]?.id))
// console.log(arr.map(el => ({...el, post_categories: el.post_categories.filter(post => post.id === el.category)})))
Is this what you are looking for?

What's the proper way to iterate through and return possibly multiple items in an API response? [duplicate]

This question already has answers here:
Loop through an array in JavaScript
(46 answers)
Closed 2 years ago.
Here is one API call I created for an SDK that returns a Javascript object with various fields:
listProjects(company_id) {
return axios.get(BASE_URL + 'projects?company_id=' + company_id, {
headers: {
Authorization: this.access_token
}
})
.then(function (response) {
//console.log(response.data);
const obj = response.data;
var return_obj = { //needs to return data for all the projects not just the first
id: obj[0].id,
name: obj[0].name,
display_name: obj[0].display_name,
address: obj[0].address,
city: obj[0].city,
state_code: obj[0].state_code,
country_code: obj[0].country_code,
zip: obj[0].zip,
latitude: obj[0].latitude,
longitude: obj[0].longitude
};
return return_obj;
})
.catch(function (error) {
console.log(error);
return error;
});
}
The response looks like the following where there could possibly be multiple projects. I'm not sure how I should iterate through without hard coding a fixed length loop and how I should structure my return object accordingly.
[
{
"id": 20789,
"name": "Sandbox Test Project",
"display_name": "1234 - Sandbox Test Project",
"project_number": "1234",
"address": "6309 Carpinteria Avenue",
"city": "Carpinteria",
"state_code": "CA",
"country_code": "US",
"zip": "93013",
"county": "Santa Barbara County",
"time_zone": "US/Pacific",
"latitude": 34.3850438,
"longitude": -119.4908492,
"stage": "None",
"phone": null,
"created_at": "2020-04-03T00:35:03Z",
"updated_at": "2020-04-03T00:45:17Z",
"active": true,
"origin_id": null,
"origin_data": null,
"origin_code": null,
"owners_project_id": null,
"estimated_value": null,
"project_region_id": null,
"project_bid_type_id": null,
"project_owner_type_id": null,
"photo_id": 310560,
"start_date": null,
"completion_date": null,
"total_value": null,
"accounting_project_number": null,
"store_number": null,
"designated_market_area": null,
"company": {
"id": 27669,
"name": "Example Procore App"
}
},
{
"id": 20758,
"name": "Standard Project Template",
"display_name": "Standard Project Template",
"project_number": null,
"address": null,
"city": null,
"state_code": null,
"country_code": null,
"zip": null,
"county": null,
"time_zone": "US/Pacific",
"latitude": null,
"longitude": null,
"stage": "None",
"phone": null,
"created_at": "2020-04-03T00:25:02Z",
"updated_at": "2020-04-03T00:30:01Z",
"active": true,
"origin_id": null,
"origin_data": null,
"origin_code": null,
"owners_project_id": null,
"estimated_value": null,
"project_region_id": null,
"project_bid_type_id": null,
"project_owner_type_id": null,
"photo_id": null,
"start_date": null,
"completion_date": null,
"total_value": null,
"accounting_project_number": null,
"store_number": null,
"designated_market_area": null,
"company": {
"id": 27669,
"name": "Example Procore App"
}
}
]
You could loop through the results
listProjects(company_id) {
return axios.get(BASE_URL + 'projects?company_id=' + company_id, {
headers: {
Authorization: this.access_token
}
})
.then(function (response) {
//console.log(response.data);
//const obj = response.data;
var return_array = [];
for (var i=0; i<response.data.length; i++){ //iterate
var obj = { //construct i-th object
id: response.data[i].id,
name: response.data[i].name,
display_name: response.data[i].display_name,
address: response.data[i].address,
city: response.data[i].city,
state_code: response.data[i].state_code,
country_code: response.data[i].country_code,
zip: response.data[i].zip,
latitude: response.data[i].latitude,
longitude: response.data[i].longitude
};
return_array.push(obj); //push object to array
}
return return_array; //return array with all the objects
})
.catch(function (error) {
console.log(error);
return error;
});
}
From your code I can see that you are just reassigning the value with the same key names. So instead of returning return return_obj; Why dont you simply return obj[0]; Which already have key value pairs.
Description
You are looking for a for loop or a forEach loop on response.data.forEach(element => { //loop code }); if using a for loop you'd want to use for (let i = 0; i < response.data.length; i++) { //loop over response.data[i] }
Examples
for loop
let data = [
{
"id": 20789,
"name": "Sandbox Test Project",
"display_name": "1234 - Sandbox Test Project",
"project_number": "1234",
"address": "6309 Carpinteria Avenue",
"city": "Carpinteria",
"state_code": "CA",
"country_code": "US",
"zip": "93013",
"county": "Santa Barbara County",
"time_zone": "US/Pacific",
"latitude": 34.3850438,
"longitude": -119.4908492,
"stage": "None",
"phone": null,
"created_at": "2020-04-03T00:35:03Z",
"updated_at": "2020-04-03T00:45:17Z",
"active": true,
"origin_id": null,
"origin_data": null,
"origin_code": null,
"owners_project_id": null,
"estimated_value": null,
"project_region_id": null,
"project_bid_type_id": null,
"project_owner_type_id": null,
"photo_id": 310560,
"start_date": null,
"completion_date": null,
"total_value": null,
"accounting_project_number": null,
"store_number": null,
"designated_market_area": null,
"company": {
"id": 27669,
"name": "Example Procore App"
}
},
{
"id": 20758,
"name": "Standard Project Template",
"display_name": "Standard Project Template",
"project_number": null,
"address": null,
"city": null,
"state_code": null,
"country_code": null,
"zip": null,
"county": null,
"time_zone": "US/Pacific",
"latitude": null,
"longitude": null,
"stage": "None",
"phone": null,
"created_at": "2020-04-03T00:25:02Z",
"updated_at": "2020-04-03T00:30:01Z",
"active": true,
"origin_id": null,
"origin_data": null,
"origin_code": null,
"owners_project_id": null,
"estimated_value": null,
"project_region_id": null,
"project_bid_type_id": null,
"project_owner_type_id": null,
"photo_id": null,
"start_date": null,
"completion_date": null,
"total_value": null,
"accounting_project_number": null,
"store_number": null,
"designated_market_area": null,
"company": {
"id": 27669,
"name": "Example Procore App"
}
}
]
for (let i = 0; i < data.length; i++) {
console.log('index', i, data[i]);
}
foreach loop
let data = [
{
"id": 20789,
"name": "Sandbox Test Project",
"display_name": "1234 - Sandbox Test Project",
"project_number": "1234",
"address": "6309 Carpinteria Avenue",
"city": "Carpinteria",
"state_code": "CA",
"country_code": "US",
"zip": "93013",
"county": "Santa Barbara County",
"time_zone": "US/Pacific",
"latitude": 34.3850438,
"longitude": -119.4908492,
"stage": "None",
"phone": null,
"created_at": "2020-04-03T00:35:03Z",
"updated_at": "2020-04-03T00:45:17Z",
"active": true,
"origin_id": null,
"origin_data": null,
"origin_code": null,
"owners_project_id": null,
"estimated_value": null,
"project_region_id": null,
"project_bid_type_id": null,
"project_owner_type_id": null,
"photo_id": 310560,
"start_date": null,
"completion_date": null,
"total_value": null,
"accounting_project_number": null,
"store_number": null,
"designated_market_area": null,
"company": {
"id": 27669,
"name": "Example Procore App"
}
},
{
"id": 20758,
"name": "Standard Project Template",
"display_name": "Standard Project Template",
"project_number": null,
"address": null,
"city": null,
"state_code": null,
"country_code": null,
"zip": null,
"county": null,
"time_zone": "US/Pacific",
"latitude": null,
"longitude": null,
"stage": "None",
"phone": null,
"created_at": "2020-04-03T00:25:02Z",
"updated_at": "2020-04-03T00:30:01Z",
"active": true,
"origin_id": null,
"origin_data": null,
"origin_code": null,
"owners_project_id": null,
"estimated_value": null,
"project_region_id": null,
"project_bid_type_id": null,
"project_owner_type_id": null,
"photo_id": null,
"start_date": null,
"completion_date": null,
"total_value": null,
"accounting_project_number": null,
"store_number": null,
"designated_market_area": null,
"company": {
"id": 27669,
"name": "Example Procore App"
}
}
];
data.forEach(element => {
console.log(element);
});
References
JavaScript Foreach
Array length

Lodash filter given json array with multiple condition

I have a json array like below and I use lodash for filtering
const data = [
{
"id": "66b2bc0b-2486-4bb0-a93c-0337ebe1d647",
"company_id": "41c56094-ed7e-4fa3-a83e-2e93c6ea5750",
"name": null,
"type": null,
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921WF-001E5E02C002",
"location_id": null,
"status": null,
"updated_at": "2020-11-17T07:05:57.037Z",
"created_at": "2020-11-17T07:05:57.037Z",
"created_by": null,
"updated_by": null
},
{
"id": "975c51f8-a6cb-4701-aaa6-077f8a9974a5",
"company_id": "41c56094-ed7e-4fa3-a83e-2e93c6ea5750",
"location_id": null,
"type": null,
"name": null,
"model": null,
"status": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921WF-001E5E02C001",
"created_by": null,
"updated_by": null,
"created_at": "2020-11-17T07:05:57.015Z",
"updated_at": "2020-11-17T07:05:57.167Z"
},
{
"id": "c4d5e446-c137-443c-a4d7-2c54c204c018",
"company_id": "fe49fc61-729d-4a68-8cef-1a4041ff739e",
"name": null,
"type": null,
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921TH-001E5E02C001_Naveen",
"location_id": null,
"status": "active",
"updated_at": "2020-11-18T12:10:56.027Z",
"created_at": "2020-11-18T12:10:56.027Z",
"created_by": null,
"updated_by": null
},
{
"id": "9287ce48-e60b-4e8a-96a5-cbedd1ee3be2",
"company_id": "fe49fc61-729d-4a68-8cef-1a4041ff739e",
"name": null,
"type": "smart-plug",
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921TH-001E5E02C002",
"location_id": null,
"status": null,
"updated_at": "2020-11-18T12:11:21.867Z",
"created_at": "2020-11-18T12:11:21.867Z",
"created_by": null,
"updated_by": null
},
{
"id": "6bf58e90-6a84-480e-b944-2cabb90f60c9",
"company_id": "fe49fc61-729d-4a68-8cef-1a4041ff739e",
"name": null,
"type": "gateway",
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921GW-001E5E02C002",
"location_id": null,
"status": "active",
"updated_at": "2020-11-18T12:12:23.431Z",
"created_at": "2020-11-18T12:12:23.431Z",
"created_by": null,
"updated_by": null
}
]
I need to filter the array based on multiple conditions for eg
filter from data where { status: "active","type": "gateway"};
It should return all the objects satisfying this condition. The where condition should be dynamic and should accept any supported field for filtering. I tried the below but unable to add multiple conditions
const filteredData = lodash.find(data, ['status', 'active']);
Is there a way to do it if so please help me with a sample code
For filtering the data you can use filter method of lodash library. I have attached a code snippet. Hope this helps to solve the problem.
const data = [{
"id": "66b2bc0b-2486-4bb0-a93c-0337ebe1d647",
"company_id": "41c56094-ed7e-4fa3-a83e-2e93c6ea5750",
"name": null,
"type": null,
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921WF-001E5E02C002",
"location_id": null,
"status": null,
"updated_at": "2020-11-17T07:05:57.037Z",
"created_at": "2020-11-17T07:05:57.037Z",
"created_by": null,
"updated_by": null
},
{
"id": "975c51f8-a6cb-4701-aaa6-077f8a9974a5",
"company_id": "41c56094-ed7e-4fa3-a83e-2e93c6ea5750",
"location_id": null,
"type": null,
"name": null,
"model": null,
"status": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921WF-001E5E02C001",
"created_by": null,
"updated_by": null,
"created_at": "2020-11-17T07:05:57.015Z",
"updated_at": "2020-11-17T07:05:57.167Z"
},
{
"id": "c4d5e446-c137-443c-a4d7-2c54c204c018",
"company_id": "fe49fc61-729d-4a68-8cef-1a4041ff739e",
"name": null,
"type": null,
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921TH-001E5E02C001_Naveen",
"location_id": null,
"status": "active",
"updated_at": "2020-11-18T12:10:56.027Z",
"created_at": "2020-11-18T12:10:56.027Z",
"created_by": null,
"updated_by": null
},
{
"id": "9287ce48-e60b-4e8a-96a5-cbedd1ee3be2",
"company_id": "fe49fc61-729d-4a68-8cef-1a4041ff739e",
"name": null,
"type": "smart-plug",
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921TH-001E5E02C002",
"location_id": null,
"status": null,
"updated_at": "2020-11-18T12:11:21.867Z",
"created_at": "2020-11-18T12:11:21.867Z",
"created_by": null,
"updated_by": null
},
{
"id": "6bf58e90-6a84-480e-b944-2cabb90f60c9",
"company_id": "fe49fc61-729d-4a68-8cef-1a4041ff739e",
"name": null,
"type": "gateway",
"model": null,
"serial_number": null,
"mac_address": null,
"firmware_verison": null,
"gateway_id": null,
"device_code": "ST921GW-001E5E02C002",
"location_id": null,
"status": "active",
"updated_at": "2020-11-18T12:12:23.431Z",
"created_at": "2020-11-18T12:12:23.431Z",
"created_by": null,
"updated_by": null
}
];
const filteredData = _.filter(data, {
status: "active",
type: "gateway"
})
console.log(filteredData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

How to get a certain word or number from a block of text using cheerio JS

I am wondering how to get all of the sets of numbers that come after "id": on each line of this link using Cheerio in JS:
https://kith.com/collections/mens-footwear/products/nkcw7297-100.json
Example:
[{
"id": 19437838336128,
"product_id": 2069464547456,
"title": "3",
"price": "110.00",
"sku": "12757001",
"position": 1,
"compare_at_price": "",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "3",
"option2": null,
"option3": null,
"created_at": "2020-07-13T07:24:00-04:00",
"updated_at": "2020-07-14T08:07:57-04:00",
"taxable": true,
"barcode": null,
"grams": 1361,
"image_id": null,
"weight": 3.0,
"weight_unit": "lb",
"tax_code": "PC040100",
"requires_shipping": true
}, {
"id": 19437838368896,
"product_id": 2069464547456,
"title": "3.5",
"price": "110.00",
"sku": "194496645118",
"position": 2,
"compare_at_price": "",
"fulfillment_service": "manual",
"inventory_management": "shopify",
"option1": "3.5",
"option2": null,
"option3": null,
"created_at": "2020-07-13T07:24:00-04:00",
"updated_at": "2020-07-31T17:38:25-04:00",
"taxable": true,
"barcode": null,
"grams": 1361,
"image_id": null,
"weight": 3.0,
"weight_unit": "lb",
"tax_code": "PC040100",
"requires_shipping": true
},
So I'd want to be able to get the 2 variants after "id": at the start of each item. (1st is 19437838336128 & second is 19437838368896 )
You don't DOM manipulation for that. You can use fetch (use node.js polyfill);
fetch('https://kith.com/collections/mens-footwear/products/nkcw7297-100.json')
.then(res => res.json())
.then(data => {
let variantsIds = data.product.variants.map(p => p.id);
})
.catch(console.log)

Creating an array of arrays without any duplication Javascript

Javascript newbie here :) I want to achieve sth but can't figure it out.
Here is my data .
<pre>
[
[
{
"id": 2759178563,
"title": "Ergonomic Paper Computer",
"handle": "ergonomic-paper-computer",
"body_html": "Enable turn-key infrastructures",
"published_at": "2015-09-23T20:51:49-04:00",
"created_at": "2015-09-23T20:51:49-04:00",
"updated_at": "2015-09-23T20:51:49-04:00",
"vendor": "Schinner Inc",
"product_type": "Computer",
"tags": [
"Computer",
"Ergonomic",
"Paper"
],
"variants": [
{
"id": 8041863299,
"title": "White",
"option1": "White",
"option2": null,
"option3": null,
"price": "67.25",
"grams": 5145,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 1,
"product_id": 2759178563,
"created_at": "2015-09-23T20:51:49-04:00",
"updated_at": "2015-09-23T20:51:49-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041863363,
"title": "Mint green",
"option1": "Mint green",
"option2": null,
"option3": null,
"price": "29.58",
"grams": 6860,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 2,
"product_id": 2759178563,
"created_at": "2015-09-23T20:51:49-04:00",
"updated_at": "2015-09-23T20:51:49-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041863491,
"title": "Yellow",
"option1": "Yellow",
"option2": null,
"option3": null,
"price": "54.19",
"grams": 6045,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 3,
"product_id": 2759178563,
"created_at": "2015-09-23T20:51:49-04:00",
"updated_at": "2015-09-23T20:51:49-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041863555,
"title": "Blue",
"option1": "Blue",
"option2": null,
"option3": null,
"price": "22.88",
"grams": 9526,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 4,
"product_id": 2759178563,
"created_at": "2015-09-23T20:51:49-04:00",
"updated_at": "2015-09-23T20:51:49-04:00",
"available": true,
"featured_image": null
}
],
"images": [
{
"id": 5642046019,
"created_at": "2015-09-23T20:51:49-04:00",
"position": 1,
"updated_at": "2015-09-23T20:51:49-04:00",
"product_id": 2759178563,
"variant_ids": [],
"src": "https://cdn.shopify.com/s/files/1/1000/7970/products/Ergonomic_20Paper_20Computer.png?v=1443055909"
}
],
"options": [
{
"name": "Title",
"position": 1,
"values": [
"White",
"Mint green",
"Yellow",
"Blue"
]
}
]
},
{
"id": 2759192387,
"title": "Heavy Duty Concrete Keyboard",
"handle": "heavy-duty-concrete-keyboard",
"body_html": "Strategize synergistic e-markets",
"published_at": "2015-09-23T20:52:07-04:00",
"created_at": "2015-09-23T20:52:07-04:00",
"updated_at": "2015-09-23T20:52:07-04:00",
"vendor": "Stiedemann and Sons",
"product_type": "Keyboard",
"tags": [
"Concrete",
"Duty",
"Heavy",
"Keyboard"
],
"variants": [
{
"id": 8041883779,
"title": "Magenta",
"option1": "Magenta",
"option2": null,
"option3": null,
"price": "14.20",
"grams": 3030,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 1,
"product_id": 2759192387,
"created_at": "2015-09-23T20:52:07-04:00",
"updated_at": "2015-09-23T20:52:07-04:00",
"available": true,
"featured_image": null
}
],
"images": [
{
"id": 5642056899,
"created_at": "2015-09-23T20:52:07-04:00",
"position": 1,
"updated_at": "2015-09-23T20:52:07-04:00",
"product_id": 2759192387,
"variant_ids": [],
"src": "https://cdn.shopify.com/s/files/1/1000/7970/products/Heavy_20Duty_20Concrete_20Keyboard.png?v=1443055927"
}
],
"options": [
{
"name": "Title",
"position": 1,
"values": [
"Magenta"
]
}
]
}
],
[
{
"id": 2759168323,
"title": "Awesome Cotton Computer",
"handle": "awesome-cotton-computer-1",
"body_html": "Brand synergistic applications",
"published_at": "2015-09-23T20:51:24-04:00",
"created_at": "2015-09-23T20:51:24-04:00",
"updated_at": "2015-09-23T20:51:24-04:00",
"vendor": "Hills Group",
"product_type": "Computer",
"tags": [
"Awesome",
"Computer",
"Cotton"
],
"variants": [
{
"id": 8041841795,
"title": "Black",
"option1": "Black",
"option2": null,
"option3": null,
"price": "2.05",
"grams": 1906,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 1,
"product_id": 2759168323,
"created_at": "2015-09-23T20:51:24-04:00",
"updated_at": "2015-09-23T20:51:24-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041841859,
"title": "Orchid",
"option1": "Orchid",
"option2": null,
"option3": null,
"price": "10.78",
"grams": 4970,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 2,
"product_id": 2759168323,
"created_at": "2015-09-23T20:51:24-04:00",
"updated_at": "2015-09-23T20:51:24-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041841923,
"title": "Tan",
"option1": "Tan",
"option2": null,
"option3": null,
"price": "50.54",
"grams": 6738,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 3,
"product_id": 2759168323,
"created_at": "2015-09-23T20:51:24-04:00",
"updated_at": "2015-09-23T20:51:24-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041841987,
"title": "Teal",
"option1": "Teal",
"option2": null,
"option3": null,
"price": "91.51",
"grams": 8718,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 4,
"product_id": 2759168323,
"created_at": "2015-09-23T20:51:24-04:00",
"updated_at": "2015-09-23T20:51:24-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041842051,
"title": "Gold",
"option1": "Gold",
"option2": null,
"option3": null,
"price": "8.24",
"grams": 194,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 5,
"product_id": 2759168323,
"created_at": "2015-09-23T20:51:24-04:00",
"updated_at": "2015-09-23T20:51:24-04:00",
"available": true,
"featured_image": null
}
],
"images": [
{
"id": 5642032131,
"created_at": "2015-09-23T20:51:24-04:00",
"position": 1,
"updated_at": "2015-09-23T20:51:24-04:00",
"product_id": 2759168323,
"variant_ids": [],
"src": "https://cdn.shopify.com/s/files/1/1000/7970/products/Awesome_20Cotton_20Computer_f74fc2a4-efa5-42ca-a3b2-36c378f1c003.png?v=1443055884"
}
],
"options": [
{
"name": "Title",
"position": 1,
"values": [
"Black",
"Orchid",
"Tan",
"Teal",
"Gold"
]
}
]
},
{
"id": 2759192387,
"title": "Heavy Duty Concrete Keyboard",
"handle": "heavy-duty-concrete-keyboard",
"body_html": "Strategize synergistic e-markets",
"published_at": "2015-09-23T20:52:07-04:00",
"created_at": "2015-09-23T20:52:07-04:00",
"updated_at": "2015-09-23T20:52:07-04:00",
"vendor": "Stiedemann and Sons",
"product_type": "Keyboard",
"tags": [
"Concrete",
"Duty",
"Heavy",
"Keyboard"
],
"variants": [
{
"id": 8041883779,
"title": "Magenta",
"option1": "Magenta",
"option2": null,
"option3": null,
"price": "14.20",
"grams": 3030,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 1,
"product_id": 2759192387,
"created_at": "2015-09-23T20:52:07-04:00",
"updated_at": "2015-09-23T20:52:07-04:00",
"available": true,
"featured_image": null
}
],
"images": [
{
"id": 5642056899,
"created_at": "2015-09-23T20:52:07-04:00",
"position": 1,
"updated_at": "2015-09-23T20:52:07-04:00",
"product_id": 2759192387,
"variant_ids": [],
"src": "https://cdn.shopify.com/s/files/1/1000/7970/products/Heavy_20Duty_20Concrete_20Keyboard.png?v=1443055927"
}
],
"options": [
{
"name": "Title",
"position": 1,
"values": [
"Magenta"
]
}
]
}
],
[
{
"id": 2759167747,
"title": "Awesome Bronze Computer",
"handle": "awesome-bronze-computer",
"body_html": "Orchestrate holistic web services",
"published_at": "2015-09-23T20:51:20-04:00",
"created_at": "2015-09-23T20:51:20-04:00",
"updated_at": "2015-09-23T20:51:20-04:00",
"vendor": "Zboncak-Kemmer",
"product_type": "Computer",
"tags": [
"Awesome",
"Bronze",
"Computer"
],
"variants": [
{
"id": 8041840195,
"title": "Magenta",
"option1": "Magenta",
"option2": null,
"option3": null,
"price": "56.69",
"grams": 6035,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 1,
"product_id": 2759167747,
"created_at": "2015-09-23T20:51:20-04:00",
"updated_at": "2015-09-23T20:51:20-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041840259,
"title": "Mint green",
"option1": "Mint green",
"option2": null,
"option3": null,
"price": "63.89",
"grams": 9961,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 2,
"product_id": 2759167747,
"created_at": "2015-09-23T20:51:20-04:00",
"updated_at": "2015-09-23T20:51:20-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041840323,
"title": "Maroon",
"option1": "Maroon",
"option2": null,
"option3": null,
"price": "18.76",
"grams": 922,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 3,
"product_id": 2759167747,
"created_at": "2015-09-23T20:51:20-04:00",
"updated_at": "2015-09-23T20:51:20-04:00",
"available": true,
"featured_image": null
},
{
"id": 8041840387,
"title": "Salmon",
"option1": "Salmon",
"option2": null,
"option3": null,
"price": "97.60",
"grams": 1355,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 4,
"product_id": 2759167747,
"created_at": "2015-09-23T20:51:20-04:00",
"updated_at": "2015-09-23T20:51:20-04:00",
"available": true,
"featured_image": null
}
],
"images": [
{
"id": 5642031235,
"created_at": "2015-09-23T20:51:20-04:00",
"position": 1,
"updated_at": "2015-09-23T20:51:20-04:00",
"product_id": 2759167747,
"variant_ids": [],
"src": "https://cdn.shopify.com/s/files/1/1000/7970/products/Awesome_20Bronze_20Computer.png?v=1443055880"
}
],
"options": [
{
"name": "Title",
"position": 1,
"values": [
"Magenta",
"Mint green",
"Maroon",
"Salmon"
]
}
]
},
{
"id": 2759192387,
"title": "Heavy Duty Concrete Keyboard",
"handle": "heavy-duty-concrete-keyboard",
"body_html": "Strategize synergistic e-markets",
"published_at": "2015-09-23T20:52:07-04:00",
"created_at": "2015-09-23T20:52:07-04:00",
"updated_at": "2015-09-23T20:52:07-04:00",
"vendor": "Stiedemann and Sons",
"product_type": "Keyboard",
"tags": [
"Concrete",
"Duty",
"Heavy",
"Keyboard"
],
"variants": [
{
"id": 8041883779,
"title": "Magenta",
"option1": "Magenta",
"option2": null,
"option3": null,
"price": "14.20",
"grams": 3030,
"compare_at_price": null,
"sku": "",
"requires_shipping": true,
"taxable": true,
"position": 1,
"product_id": 2759192387,
"created_at": "2015-09-23T20:52:07-04:00",
"updated_at": "2015-09-23T20:52:07-04:00",
"available": true,
"featured_image": null
}
],
"images": [
{
"id": 5642056899,
"created_at": "2015-09-23T20:52:07-04:00",
"position": 1,
"updated_at": "2015-09-23T20:52:07-04:00",
"product_id": 2759192387,
"variant_ids": [],
"src": "https://cdn.shopify.com/s/files/1/1000/7970/products/Heavy_20Duty_20Concrete_20Keyboard.png?v=1443055927"
}
],
"options": [
{
"name": "Title",
"position": 1,
"values": [
"Magenta"
]
}
]
}
]
]
</pre>
And here is my code:
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
#Injectable()
export class ShopifyService {
/**
* Initialization
*/
constructor (
private http: Http
) {}
private shopifyUrl = 'app/heroes.json';
errorMessage: string;
/**
* Private Methods
*/
fetchProducts(): Promise<Response> {
return this.http.get(this.shopifyUrl)
.toPromise()
.then(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
if (body.data) {
return body.data;
}
else if (body.products) {
return body.products;
}
else {
return { };
}
}
private handleError (error: any) {
let errMsg = error.message || 'Server error';
console.error(errMsg);
return Promise.reject(errMsg);
}
private filterProducts(list, archetype) {
var result = [];
for (var i = 0; i < list.length; i++) {
if (list[i].product_type === archetype) {
result.push(list[i]);
}
}
return result;
}
/**
* Public Methods
*/
public findProducts(archetypes) {
return this.fetchProducts().then(
products => {
var result = [],
fetchedResponse = [];
for (var i = 0; i < archetypes.length; i++) {
fetchedResponse = this.filterProducts(
products, archetypes[i]
);
result = result.concat(fetchedResponse);
}
return result;
},
error => this.errorMessage = <any>error
)
}
public findSingleProductVariant() {
var result = [],
j = 0;
return this.findVariants().then(
product => {
for (var i = 0; i < product.length; i++) {
// console.log(product[i]);
}
}
);
// return result;
}
findVariants() {
return this.findProducts(['Computer', 'Keyboard']).then(
products => {
var result = [];
for (var i = 0; i < products.length; i++) {
if (products[i].product_type === 'Computer') {
for (var j = 0; j < products.length; j++) {
if (products[j].product_type === 'Keyboard') {
result.push([products[i], products[j]]);
}
}
}
}
console.log(result);
return result;
}
)
}
}
Until here I got to half of what. An array of two dimensional arrays (one of them is from keyboard type and another one from computer type).
It is sth like this ==>
[
[
[Computer_A],
[Keyboard_A]
],
[
[Computer_B],
[Keyboard_A]
],
[
[Computer_C],
[Keyboard_A]
],
]
Now each one of these objects have its own array of variants. I have to modify my findSingleProductVariant in order to go over each one of these arrays, pick a keyboard variant (which its array has a price field), also pick a computer variant and calculate the price. If the price is less than 1000, it can continue picking another keyboard and computer. But the thing is that it can't have two identical arrays. for instance we can't have sth like this.
[
['Computer_A'], ['Keyboard_A'],
['Computer_A'], ['Keyboard_A'],
]
The key thing here is that you can't directly compare objects and expect relevant results, e.g.
['Red Lamp', 'Blue Table'] === ['Red Lamp', 'Blue Table']
will return false (Array.indexOf() also won't work as expected since it uses strict comparison).
So for an array of arrays, you will have to use two nested loops to get down to comparing primitive values.

Categories