Put JSON data inside another object of the same JSON - javascript

I need to put the images that are on "included" into "data:{relationships: { field_imagen: { data" but the problem is that i just managed to put only the first image into every index using map and find
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
And this is my json (example node)
{
"data": [
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
}
],
}
]
},
this is the included object, who is in the same level as data
"included": [
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
},
,
Expected Result:
"data": [
"relationships": {
"type": "node--actualidad_institucional",
"id": "71514647-af49-4136-8a28-9563d133070a",
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
}
}
},
I put the uri from included into field_imagen. Tried to resolve like that, but it just put only the first image of the Array from the included object in every node:
showNoticias() {
this.frontService.getNoticias()
.subscribe((data: Noticias) => {
this.noticiasImages = Array.from(data.included);
this.noticiasData = Array.from(data.data);
let noticiasImages = this.noticiasImages.map((data: {id: any}) => data.id);
let noticiasData = this.noticiasData.map((data:{relationships: { field_imagen: { data: { id: any; }}}}) => data.relationships.field_imagen.data.id);
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
console.log(data);
});
}
Hope you can help me, thanks!
UPDATE: tried that but didnt work like expected
let merged = data.data.map((data:{relationships: { field_imagen: { data: any }}}) => Object.assign({}, noticiasImages));
console.log(data)
console.log(merged)

Sometimes using regular for loops are a better option. Using map with objects that have that many properties can get confusing. And using forEach will not give you access to the i index of the iteration in the loop, which makes things easier in this case.
for (let i = 0; i < obj.included.length; i++) {
let uri = obj.included[i].attributes.uri;
obj.data[i].relationships.field_imagen.data[0] = {
...obj.data[i].relationships.field_imagen.data[0],
...uri
}
}
console.log(obj)
Output:
{
"data": [
{
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
]
}
}
}
],
"included": [
{
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
}
}
]
}

Related

Nested for loop through json object array does not work

I need to build a new array based on json array (Context) bellow. Unfortunately I never reach the outer Loop after passing by first run. Is there any mistake in code? How can I solve this issue?
Thank you for help.
Context:
"rfqBp": [
{
"rfqBpId": 1041650,
"Contact": [
{
"ID": 1000014,
"SelectedContact": true
},
{
"ID": 1002411,
"SelectedContact": true
},
{
"ID": 1016727,
"SelectedContact": true
},
{
"ID": 1017452,
"SelectedContact": true
}
],
},
{
"rfqBpId": 1052326,
"Contact": [
{
"ID": 1016236,
"SelectedContact": true
},
{
"ID": 1019563,
"SelectedContact": true
}
],
},
{
"rfqBpId": 1056632,
"Contact": [
{
"ID": -1,
"SelectedContact": false
}
],
},
{
"rfqBpId": 1056637,
"Contact": [
{
"ID": 1019875,
"SelectedContact": true
}
],
}
],
script:
$scope.SelectedContacts = function() { //function starts by click on checkbox in html
let selectedContactList = [];
let finalList = [];
$scope.Context.Output = [];
for (let i = 0; i <= $scope.Context.rfqBp.length; i++) {
for (let j = 0; j <= $scope.Context.rfqBp[i].Contact.length; j++) {
if ($scope.Context.rfqBp[i].Contact[j].SelectedContact === true) {
selectedContactList = {
"ID": $scope.Context.rfqBp[i].Contact[j].ID
};
finalList.push(selectedContactList);
} else if ($scope.Context.rfqBp[i].Contact[j].SelectedContact !== true) {
continue;
}
$scope.Context.Output = finalList; //Output works but just for rfqBp[1]
};
};
$scope.Context.Output = finalList; //this part never reached
};
Output:
"Output": [
{
"ID": 1000014
},
{
"ID": 1016727
},
{
"ID": 1017452
}
]
I try to get following:
"Output": [
{
"ID": 1000014
},
{
"ID": 1016727
},
{
"ID": 1017452
},
{
"ID": 1016236
},
{
"ID": 1019563
},
{
"ID": 1019875
}
]
You can use Array.prototype.flatMap() combined with Array.prototype.filter(), Array.prototype.map() and Destructuring assignment:
const rfqBp = [{rfqBpId: 1041650,Contact: [{ID: 1000014,SelectedContact: true,},{ID: 1002411,SelectedContact: true,},{ID: 1016727,SelectedContact: true,},{ID: 1017452,SelectedContact: true,},],},{rfqBpId: 1052326,Contact: [{ID: 1016236,SelectedContact: true,},{ID: 1019563,SelectedContact: true,},],},{rfqBpId: 1056632,Contact: [{ID: -1,SelectedContact: false,},],},{rfqBpId: 1056637,Contact: [{ID: 1019875,SelectedContact: true,},],},]
const result = rfqBp
.flatMap(({ Contact }) => Contact
.filter(({ ID }) => ID > 0) // Filter to exclude negative `ID`s
.map(({ ID }) => ({ ID }))
)
console.log(result)

Error in generating a valid json recursive javascript function

I have a function to generate an object which I'm transforming to a JSON later on:
function createSearchCriteria(payload) {
var output = [];
if (payload['searchCriteria'] != null) {
for (var i = 0; i < payload['searchCriteria'].length; i++) {
var content = payload['searchCriteria'][i];
output[i] = {};
if (content['grouping'] != null) {
output[i]['groupOperator'] = content['grouping'];
output[i]['searchCriteria'] = [];
output[i]['searchCriteria'].push(createSearchCriteria(content))
} else {
output[i]['name'] = content['name'];
output[i]['type'] = content['type'];
}
}
}
return output
}
The input payload for this method is also a JSON value parsed
payload = JSON.parse(request);
The input structure is almost the same as the output, the only difference is the "grouping" attribute, which in the output is called "groupOperator".
I have implemented my function recursive because we can have different levels of search criteria.
Even though the searchCriteria in the input has only one [] each.
Why does each searchCriteria in the result comes with 2 pairs of squared brackets?
{
"searchCriteria": [
{
"groupOperator": "AND",
"searchCriteria": [
[
{
"groupOperator": "OR",
"searchCriteria": [
[
{
"name": "FirstName",
"type": "string"
},
{
"name": "LastName",
"type": "string"
},
{
"name": "MiddleName",
"type": "string"
},
{
"name": "Document",
"type": "string"
},
{
"name": "DOB",
"type": "date"
},
{
"name": "CdrId",
"type": "string"
}
]
]
},
{
"groupOperator": "AND",
"searchCriteria": [
[
{
"name": "Active",
"type": "bool"
},
{
"name": "Id",
"type": "int"
},
{
"name": "CountryId",
"type": "int"
}
]
]
}
]
]
}
],
"groupOperator": "AND"
}
Thanks in advance for your help.
try
output[i]['searchCriteria'] = createSearchCriteria(content)
instead of
output[i]['searchCriteria'] = [];
output[i]['searchCriteria'].push(createSearchCriteria(content))

Javascript: How to loop through array of objects for post request for array property?

I have an array response and i need to pass post request data from that response. The response have nested array objects as well. So how to loop through those array objects into post api request key values ?
Response which i am getting is as below:
records = "data": [
{
"id": 1,
"title": "Black Panther",
"product_images": [
{
"id": 1,
"images": {
"id": 1,
"thumbnail_image": "/assets/1/image.jpg",
},
},
{
"id": 2,
"images": {
"id": 2,
"thumbnail_image": "/assets/2/image.jpg",
},
}
],
product_categories: [
{
"id": 1,
"categories": {
"id": 3,
"category_name": "Outdoor Sports"
}
}
]
}
]
Now i need to pass that product_images array object's images.thumbnail_image property into the post request key value.
records.map((element) => {
let data;
data = {
"id": element.id,
"name": element.title,
"image_files":
[
{
"url": "" // need to pass thumbnail_image value over here.
}
],
"product_category": {
"category_id": [1,2] // need to pass product_categories[i].categories.id value over here.
}
}
})
axios post API request is as below:
axios({
method: 'post',
url: 'api_url',
data: {
"products": data,
}
}).then((response) => {
console.log(response);
}).catch((error) => {
console.log(error)
});
P.S: I have tried to manage this issue with loop through into the image_files array as below but that is working.
"image_files": [
element.product_images.map((ele) => {
{
"url": ele.images.thumbnail_image
}
})
]
::Updated::
I also need to manage that category property into the post api request. I have tried like this way but it pass the [null] value
"category_id": lists.campaign_product_categories.map((element) => {
let arr = []
arr.push(element.categories.id)
}),
You can use a nested map statement with destructuring to achieve this.
let records = [ { "id": 1, "title": "Black Panther", "product_images": [ { "id": 1, "images": { "id": 1, "thumbnail_image": "/assets/1/image.jpg", }, }, { "id": 2, "images": { "id": 2, "thumbnail_image": "/assets/2/image.jpg", }, } ] } ];
let data = records.map(({id, title:name, product_images}) => (
{
id, name,
"image_files": product_images.map(({images:{thumbnail_image: url}})=>({
url
}))
}
));
console.log(data);
You can just map the sub array for each array element like so:
const records = [
{
id: 1,
title: "Black Panther",
product_images: [
{
id: 1,
images: {
id: 1,
thumbnail_image: "/assets/1/image.jpg",
},
},
{
id: 2,
images: {
id: 2,
thumbnail_image: "/assets/2/image.jpg",
},
},
],
},
];
const mapped = records.map((element) => ({
id: element.id,
name: element.title,
image_files: element.product_images.map((i) => ({
url: i.images.thumbnail_image,
})),
}));
console.log(mapped);
You need to run a map on the product images inner array to create the URL array
let apiResponses = records.data.map((dataElement) => {
let urls = dataElement.product_images.map((product_image) => {
return {"url": product_image.images.thumbnail_image}
})
return {
"id": dataElement.id,
"name": dataElement.title,
"image_files":
urls,
}
})
console.log(apiResponses[0])
Outputs
{
id: 1,
name: 'Black Panther',
image_files: [ { url: '/assets/1/image.jpg' }, { url: '/assets/2/image.jpg' } ]
}
Full code below
let records = {"data": [
{
"id": 1,
"title": "Black Panther",
"product_images": [
{
"id": 1,
"images": {
"id": 1,
"thumbnail_image": "/assets/1/image.jpg",
},
},
{
"id": 2,
"images": {
"id": 2,
"thumbnail_image": "/assets/2/image.jpg",
},
}
]
}
]}
let apiResponses = records.data.map((dataElement) => {
let urls = dataElement.product_images.map((product_image) => {
return {"url": product_image.images.thumbnail_image}
})
return {
"id": dataElement.id,
"name": dataElement.title,
"image_files":
urls,
}
})
console.log(apiResponses[0])
You forgot the return statement
records.map((element) => {
let data;
data = {
"id": element.id,
"name": element.title,
"image_files":
[
{
"url": "" // need to pass thumbnail_image value over here.
}
],
}
return data; // <------- this line
})

How grab key from api call in this js example

So in the API response example below, focusing on env_variables, I am trying grab the value for secret. I am stuck because as you can see, the name and value are not nested together. I am not familiar with how to grab the value based on the name in this example.
api response:
{
"id": 1146,
"job": {
"name": "jobname1",
},
"env_variables": [
{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
],
},
{
"id": 1147,
"job": {
"name": "jobname2",
},
"env_variables": [
{
"name": {
"name": "secret"
},
"value": {
"value": "10.13.7"
}
},
{
"name": {
"name": "test5"
},
"value": {
"value": "10.13.6"
}
},
],
}
js
jobs: []
apiEndpoint = "test.com/api"
fetch(this.apiEndpoint)
.then(response => response.json())
.then(body => {
for(let i=0; i<body.length; i++){
this.jobs.push({
'build_id': JSON.stringify(body[i].id),
'secret': //not sure how to pull the value (10.13.7)
})
}
})
You need nested loops, since there are two nested arrays: the top level of the response is an array of objects, and env_variables contains an array of objects.
fetch(this.apiEndpoint)
.then(response => response.json())
.then(body => {
for (let i = 0; i < body.length; i++) {
let env = body[i].env_variables;
for (let j = 0; j < env.length; j++) {
if (env[j].name.name == "secret") {
this.jobs.push({
'build_id': JSON.stringify(body[i].id),
'secret': env[j].value.value
})
}
}
}
})
You can do something like this inside .then(body=>...
const body = [{ //it looks like brackets [] were lost in OP
"id": 1146,
"job": {
"name": "jobname1",
},
"env_variables": [{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
{
"name": {
"name": "test1"
},
"value": {
"value": "10.13.6"
}
},
],
},
{
"id": 1147,
"job": {
"name": "jobname2",
},
"env_variables": [{
"name": {
"name": "secret"
},
"value": {
"value": "10.13.7"
}
},
{
"name": {
"name": "test5"
},
"value": {
"value": "10.13.6"
}
},
],
}
];
let secret = null;
body.forEach(b => {
let el = b.env_variables.find(e => e.name.name == 'secret');
if (el) { //found
secret = el.value.value;
return false; //exit forEach
}
});
console.log(secret);
You could also do something like this with Array.forEach and Array.find:
let data = [{ "id": 1146, "job": { "name": "jobname1", }, "env_variables": [{ "name": { "name": "test1" }, "value": { "value": "10.13.6" } }, { "name": { "name": "test1" }, "value": { "value": "10.13.6" } }, ], }, { "id": 1147, "job": { "name": "jobname2", }, "env_variables": [{ "name": { "name": "secret" }, "value": { "value": "10.13.7" } }, { "name": { "name": "test5" }, "value": { "value": "10.13.6" } }, ], } ]
let jobs = []
data.forEach(({id, env_variables}) => jobs.push({
build_id: id,
secret: ((env_variables.find(({name}) =>
name.name === 'secret') || {}).value || {}).value || 'N/A'
// ... other props
}))
console.log(jobs)
Assuming your result is an array, you could do something like this:
let secrets = results.reduce((result, item) => {
let secret = item["env_variables"].find((v) => {return v.name.name === "secret"})
if(secret){
result.push({id:item.id, secret: secret.value.value});
}
return result;
}, []);
This would return an array of objects like {id: 1, secret: ""} for each object in your result set that has a secret.
If you don't care whether the secret is present or not, you could modify the code slightly like this:
let secrets = results.reduce((result, item) => {
let secret = item["env_variables"].find((v) => {return v.name.name === "secret"})
result.push({id:item.id, secret: secret ? secret.value.value : ""});
return result;
}, []);
Which just leaves with you an empty string on the levels where there is no secret.

how to return an array inside an array javascript

i have an array inside an array...how do i return all the values using a for loop in javascript/angular?
for example my json...
[
{
"Name": "element1",
"Attributes": [
{"file":"document.doc"},
{"file":"document2.doc"}
]
},
{
"Name": "element2",
"Attributes": [
{"file":"document3.doc"},
{"file":"document4.doc"}
]
},
{
"Name": "element3",
"Attributes": [
{"file":"document5.doc"},
{"file":"document6.doc"}
]
}
]
having a tough time just returning all the files within attributes...only seem to be getting the first one everytime.
EDIT:
what i have so far..
function getAllFiles() {
for (var i = 0; i < Attributes.file.length; i++) {
return Attributes.file[i];
}
}
One of the methods how to get the desired output, using Array#reduce.
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s.push(...a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
ES5
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s = s.concat(a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
try
var files = [];
json.forEach(function(obj) {
obj.Attributes.forEach(function (f) {
files.push(f.file); })
});
this loops on the json array then on each element's attributes then adds the vilue of file
You could show all the files using Array methods like map and reduce:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.map(function (obj) {
return obj.Attributes.map(function (i) {
return i.file;
});
}).reduce(function (x, y) {
return x.concat(y);
});
console.log(files);
Although Kind user's answer is better:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.reduce(function(acc, val) {
return acc.concat(
val.Attributes.map(function(attribute) {
return attribute.file;
})
);
}, []);
console.log(files);
I renamed some variables so that the code makes more sense (to me).
Something like outerArray.innerArray. in your case arrayName.Attributes should work.

Categories