Fetch single array from multiple - javascript

I am making angular application where i am making a forEach function with service inside like,
this.data.forEach(function(element) => {
this.appService.getRest(element.optionsUrl, localStorage.getItem('token')).subscribe(result => {
element.options = result.data;
this.getIntake(this.data);
});
});
here i am trying to store the result comes from service to the element.options and then i am calling a function to get back the data value filled with element.options because from the service only i will get the value for options so after that i need to send this data to a function and need to retrieve it..
result.data is an array and it gives the following, [{"id":1,"name":"option1"}],[{"id":2,"name":"option2"}],[{"id":3,"name":"option3"}] respectively for three..
In this.getIntake(data); function if i console.log(data)
getIntake(data) {
console.log(data);
}
then it is giving same array multiple times with same values like..
[
{"name":"abc", value: "abc", optionUrl: "abcUrl", options: [{"id":1,"name":"option1"}]},
{"name":"def", value: "def", optionUrl: "defUrl", options: [{"id":2,"name":"option2"}]},
{"name":"ghi", value: "ghi", optionUrl: "ghiUrl", options: [{"id":3,"name":"option3"}]}
]
[
{"name":"abc", value: "abc", optionUrl: "abcUrl", options: [{"id":1,"name":"option1"}]},
{"name":"def", value: "def", optionUrl: "defUrl", options: [{"id":2,"name":"option2"}]},
{"name":"ghi", value: "ghi", optionUrl: "ghiUrl", options: [{"id":3,"name":"option3"}]}
]
[
{"name":"abc", value: "abc", optionUrl: "abcUrl", options: [{"id":1,"name":"option1"}]},
{"name":"def", value: "def", optionUrl: "defUrl", options: [{"id":2,"name":"option2"}]},
{"name":"ghi", value: "ghi", optionUrl: "ghiUrl", options: [{"id":3,"name":"option3"}]}
]
As the data has three objects, it was reflected three times..
For each object has element.optionsUrl and i need to subscribe that and need to store the data in element.options and if i came out of the service i am not getting the value in options and so i am making a function inside service and passing this.data with options to it.. In that function i am getting the data with values but i need to get completely filled data only once but it gives three as the data has three objects.. From that how to get the final only one array with filled data instead of three.
Stackblitz https://stackblitz.com/edit/angular-kwvjqu
As the service is delayed i am making the function call on run time of the service and sending the data..
How to get only one array from this multiple generated array using pure angular/typescript, javascript way??

Since you are firing the request inside the forEach for each element in your array, it will subscribe for that many times, hence you see it logs 3 times.
RxJS to help.
Instead of loop through your Array with forEach use from, it converts your Array into an array of Observable and you can then do things with it, like fire a http request.
from(this.data) //Converts your data array to array of Observables
.pipe(
mergeMap(element => {
return this.appService.getRest(element.optionsUrl, localStorage.getItem('token')) //fires http request for each element
.pipe(
map((result) => { //change the data
element.options = result.data;
return of(element); //returns an observable for each element
})
)
}),
combineAll() //combines all the observable into one
)
.subscribe(x=>{
this.getIntake(x); //x contains an array of your element
});

Related

How to retrieve array value in Node.js and send to next calling API

I am new to I have a JSON response from an API , which I need to parse two values in the JSON and then pass those value to the next API. The challenge I have is , I will have N number of Array JSON response similar to the sample I am Showing below ,this is one sample json but there will be n number of json concatenated of the same structure.
Now I want to retrieve the id and messages.messageId value within customers object and pass the same as input to next API call. How could I retrieve the matching id and message id and save it in a list to send to next API
"id":"64146c29",
"Customers":[
{
"id":"4a61aaf2-c6bc-41ae-9ecd-041825135bf5",
"startTime":"2022-11-29T16:00:07.623Z",
"endTime":"2022-11-29T16:00:07.630Z",
"attributes":{
"contactId":"30000236925961000-B1"
},
"provider":"Beta",
"peer":"7126e24c-affa-4fb8-a450-50a644764a32",
"messages":[
{
"messageId":"ce67fba0ef44523f0d9a9d5dd5649642"
}
],
"type":"sms",
"recipientCountry":"US",
"recipientType":"mobile"
},
{
"id":"bbed4f9c-1be7-4fe5-ba37-5e058e9f16c6",
"startTime":"2022-11-29T16:00:07.626Z",
"endTime":"2022-11-29T16:00:07.668Z",
"attributes":{
},
"provider":"Beta",
"peer":"fe49dd4a-012e-447b-b9fe-7667678756c7",
"messages":[
],
"type":"sms",
"recipientCountry":"US",
"recipientType":"tollfree"
}
],
"otherMediaUris":[
],
"selfUri":"64146c29-fe0d-4482-935e-8b86be878cb9"
} ````
To get this data (id and messageId) of each customer, you will have to loop over the customers array and return those value from each customer object.
const customersDataToSendToApi = customersDataFromApi.Customers.map(customer => {
return {customer.Id, customer.messages.messageId}
})
The customersDataToSendToApi is already an array which you can pass in the body of API POST request. I hope this helps.
Yes, you do the same thing to the array of multiple json since you say they have similar structure.
arrayOfMultipleJson.map(eachJson =>{
eachJson.Customers.map(customer => {
return {customer.Id, customer.messages.messageId}
})
})
Do you get the picture I am painting?
If you don't mind me asking, what scenario makes you get multiple JSON in one API call?

Iterate over JSON data in JavaScript

I am working on some trains' open data feed and getting some JSON as a response from a server. I parse this JSON into a data variable and display it as seen below. However, I cannot find a way to iterate over the response to be able to manipulate each message. I want to iterate over each message and then use the data for a record in a SQL database. I cannot get to the point of accessing any individual message data.
How can I create a loop to iterate over each message and extract it's data?
[
{
SF_MSG: {
time: '1666370311000',
area_id: 'TD',
address: '0C',
msg_type: 'SF',
data: '1F'
}
},
{
CA_MSG: {
to: '4333',
time: '1666370311000',
area_id: 'WO',
msg_type: 'CA',
from: '4331',
descr: '2K60'
}
}, ...
]
Edit: using data.forEach(function(message) produces an output of the structure:
{ CA_MSG: { to: '6021', time: '1666372120000', area_id: 'CY', msg_type: 'CA', from: 'STIN', descr: '2Y73' } }
, however, how do I query this inner object, the names of the objects will differ depending on message type if this matters?
try this:
data = JSON.parse(yourJSONdata)
data.map((o, i)=>{
//o is the object, i is the index
// do your processing here
then at the end do
data[i]=processedobject
})

Sync + Async POSTing nested parent-children objects to preserve the order

I have a nested array of Person objects.
Each Person object has a mandatory name. Each Person can also optionally have a children field that contains an array of other Person objects (that also have a children field - so the "depth" of the family tree can essentially go on forever.)
If there is no children, the children field will just be an empty array [].
E.g.
const family_name = "The Numbers";
const family = [{
name: "1",
children: [],
},
{
name: "2",
children: [{
name: "2-1",
children: [{
name: "2-1-1",
children: [],
}, ],
},
{
name: "2-2",
children: [],
}
],
},
{
name: "3",
children: [{
name: "3-1",
children: [],
}, ],
},
]
I need to POST the "parent" before the "child". When I POST a Person, I get its id back in the response.data. This id needs to be used in the immediate child's POST as a parent_id so that child will be associated to the parent.
The topmost Person will need to have their parent_id be the family_name.
Each "level" needs to be POSTed asynchronously as my back-end needs to preserve the order. (Note: Calculating the order of the Person on the client-side and passing that value to the back-end is not a solution as Person is actually a MPTT model where the insertion order matters.)
E.g. 1 then 2 then 3
E.g. 2 then 2-1 then 2-2.
However, the nested Persons can be POSTed in sync. For example, once POSTing 2 returns with a 201 response, its "sibling" 3 and its "child" 2-1 can be POSTed at the same time.
How can I optimally POST all Persons in a nested array so that the order is preserved? Please note that I am using axios.
Edit: Here is some pseudo-code:
function postPersons(persons, parent_id) {
// Async POST all objects in persons
// e.g. POST 1 then 2 then 3 to family_name
// For each successful POST, if person has children,
// async POST those children to that person
// e.g. Once POST to 2 resolves, POST 2-1 then 2-2 to 2
// e.g. Once POST to 3 resolves, POST 3-1 to 3
// Repeat for all successful POSTs
// e.g. Once POST to 2-1 resolves, POST 2-1-1 to 2-1
}
postPersons(family, family_name)
Instead of using async/await for a sequential loop, I'd recommend to use a synchronous loop and accumulate two things separately:
the promise for the child that is processed sequentially (see here or there)
an array of promises for all the recursive calls, that will be Promise.all'd in the end
This ensures proper order as well as immediate propagation of errors.
So the code will look like
function postPersons(persons, parent_id) {
const results = [];
let chain = Promise.resolve();
for (const person of persons) {
chain = chain.then(() =>
postSinglePerson(person, parent_id)
);
results.push(chain.then(result =>
postPersons(person.children, result.id)
));
}
return Promise.all(results);
}
postPersons(family, family_name).then(() => console.log('Done'), console.error);

Javascript: Construct an object from array of objects based on matching property id's:

still quite new to higher order functions and trying to use them correctly here if possible.
I have a array of objects being returned from an api constructed like so:
[ {"gymId":3467, "halls": [{ "hallId": "25828", "instructorId": 1064,
"slotIds": [2088,2089], "sessionId":8188},
{"hallId": "25848", "instructorId": 1067, "slotIds": [2088,2089], "sessionId": 8188 }]}]
Expected result I want to achieve is to create a list of objects such as this from the array above ...
{2088: [{ "hallId":"25828", "instructorId":1064, "sessionId":8188 },
{ "hallId":"25848", "instructorId":1067, "sessionId":8188 }],
2089: [{ "hallId":"25828", "instructorId":1064, "sessionId":8188 },
{ "hallId":"25848", "instructorId":1067, "sessionId":8188 }]
}
I was thinking something along the lines of this
halls.reduce((acc, hall) => {
hall.slotIdIds.forEach(slotId => {
acc[slotId] = {
//expected object properties as above here.
};
});
return acc;
}, {}),
Problem is when I reduce in this way only one hallId is being returned and not the two matching hall ids where the slots exist.
Bit perplexed as to how to solve this one and would really appreciate any tips.

How to get a value from nested JSON data

I am trying to get a value from the nested JSON data below. Specifically, the payments captures id value 0TA12948FV40723B is the value I need.
I try using the following codes to retrieve the value.
details.purchase_units.payments.captures.id
details.purchase_units.payments[0].captures.id
But I keep getting a console.log Error: "Order could not be captured"
JSON DATA
{
"create_time":"2019-02-19T05:06:52Z",
"update_time":"2019-02-19T05:06:52Z",
"id":"3HB96413YD922272B",
"intent":"CAPTURE",
"status":"COMPLETED",
"payer":{
"email_address":"a#yandex.com",
"payer_id":"WEJUPTK4U53E9",
"address":{
"address_line_1":"1 Main St",
"admin_area_2":"San Jose",
"admin_area_1":"CA",
"postal_code":"95131",
"country_code":"US"
},
"name":{
"given_name":"a",
"surname":"som"
},
"phone":{
"phone_number":{
"national_number":"408-214-8270"
}
}
},
"purchase_units":[{
"reference_id":"default",
"amount":{
"value":"1.01",
"currency_code":"USD"
},
"payee":{
"email_address":"gr-facilitator#yandex.com",
"merchant_id":"MSOIGVMKKWAMA"
},
"shipping":{
"name":{
"full_name":"Mr T"
},
"address":{
"address_line_1":"1234 Main St.",
"address_line_2":"Unit 1",
"admin_area_2":"Chicago",
"admin_area_1":"IL",
"postal_code":"60652","country_code":"US"
}
},
"payments":{
"captures":[{
"status":"COMPLETED",
"id":"0TA12948FV40723B",
"final_capture":true,
"create_time":"2019-02-20T05:06:52Z",
"update_time":"2019-02-20T05:06:52Z",
"amount":{
"value":"1.01","currency_code":"USD"
},
"seller_protection":{
"status":"ELIGIBLE",
"dispute_categories":[
"ITEM_NOT_RECEIVED",
"UNAUTHORIZED_TRANSACTION"
]}
}
]}
}]
}
Since purchase_units and captures are arrays:
details.purchase_units[0].payments.captures[0].id
captures key have objects in side an array. so you can't simply fetch like
details.purchase_units.payments[0].captures.id
you have to give the position of the captures or loop the array only you can do parsing
details.purchase_units.payments[0].captures[0].id
If you add your json as object using the chrome console you will be able to do what I did in in the image below. purchase_unit is an array so you need to access it using the index.
In case if you want to capture all the IDs in an array, you can use wild card:
details.purchase_units[*].payments.captures[*].id
This will parse complete payload for specified path and collect all the IDs in an array.

Categories