alter array of object value base on dynamic property - javascript

I have array of object like this
let arr = [
{
"james-0": {
"value": "",
"error": false
},
"john-0": {
"value": "",
"error": false
},
"jordan-0": {
"value": "",
"error": false
}
}
]
I want to alter error to true if the value is not false / empty string.
I tried this but it deosn't seem to work, I can't hardcode james-${i}
arr = arr.map((o,i) => {
let prop = o[`james-${i}`]
if(!prop.value) prop.error = true
console.log(prop)
return {
...o,
[`james-${i}`]: prop
}
})

simply that ?
let arr =
[ { "james-0": { "value": "", "error": false }
, "john-0": { "value": "abc", "error": false }
, "jordan-0": { "value": "", "error": false }
}
]
Object.keys(arr[0]).forEach( e=> arr[0][e].error = ( arr[0][e].value == ''))
console.log( arr )

You can try this approach
let arr = [
{
"james-0": {
"value": "",
"error": false
},
"john-1": {
"value": "",
"error": false
},
"jordan-2": {
"value": "val",
"error": false
}
}
];
arr = arr.map(value => {
Object.keys(value).forEach(key => {
if (!value[key].value) {
value[key].error = true;
}
})
return value;
})
console.log(arr);
.

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)

Put JSON data inside another object of the same JSON

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"
}
}
}
]
}

How to add condition to compare two array and change value of match array

I want to compare two array in that i want to change value of matching id.
Please refer bellow array's and result.
let array1 =[
{
"id": 1,
"value": false
},
{
"id": 2,
"value": false
},
{
"id": 3,
"value": true
},
{
"id": 4,
"value": false
}
]
let array2 = [
{
"id": 1
},
{
"id": 4
}
]
I want to use underscore library to compare this arrays and return the compare array value result as like below array
result = [
{
"id": 1,
"value": true
},
{
"id": 2,
"value": false
},
{
"id": 3,
"value": true
},
{
"id": 4,
"value": true
}
]
You can use Array.prototype.map():
const array1 =[{"id": 1,"value": false},{"id": 2,"value": false},{"id": 3,"value": true},{"id": 4,"value": false}]
const array2 = [{"id": 1},{"id": 4}]
const result = array1.map(({id, value}) => ({
id,
value: value || array2.some(item => item.id === id)
}))
console.log(result)
Another solution by using map
let array1 =[
{
"id": 1,
"value": false
},
{
"id": 2,
"value": false
},
{
"id": 3,
"value": true
},
{
"id": 4,
"value": false
}
]
let array2 = [
{
"id": 1
},
{
"id": 4
}
]
const resultArr = array1.map((item) => {
if (array2.findIndex((item2) => {return item2.id == item.id}) !== - 1) {
item.value = true;
}
return item;
})
console.log(resultArr);
You can use lodash.map with lodash.some to check for object and update the value.
let array1 =[ { "id": 1, "value": false }, { "id": 2, "value": false }, { "id": 3, "value": true }, { "id": 4, "value": false } ],
array2 = [ { "id": 1 }, { "id": 4 } ],
result = _.map(array1, o => ({...o, value : _.some(array2, ({id}) => id === o.id) || o.value}));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
You can try this:
array1.forEach(item => {
item.value = item.value || array2.some(item2 => item2.id === item.id)
})

Simpler way to retrieve multiple values from array

A simpler way to loop through response.Body array and retrieve values of specific elements Id and DataFields.Value - to be used in console log
RESPONSE BODY - this is what is returned when request sent in Postman
[
{
"Id": "ae61098c-eb7c-4ee8-aca7-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH127"
}
],
},
{
"Id": "84cd9a9f-d085-4642-b484-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH128"
}
],
},
{
"Id": "6629d92b-1dcf-4fc1-a019-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH129"
}
],
},
{
"Id": "47442b4f-f691-4213-b705-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH130"
}
],
}
]
MY CODE - JavaScript in Tests tab
var logReportDataQryResults = JSON.parse(responseBody);
var locationOne = 0;
var locationTwo = 1;
var locationThree = 2;
var boreholeOne = logReportDataQryResults[locationOne].Id;
const objOne = logReportDataQryResults[locationOne].DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
const holeOne = objOne ? objOne.Value : 'Not Found';
var boreholeTwo = logReportDataQryResults[locationTwo].Id;
const objTwo = logReportDataQryResults[locationTwo].DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
const holeTwo = objTwo ? objTwo.Value : 'Not Found';
var boreholeThree = logReportDataQryResults[locationThree].Id;
const objThree = logReportDataQryResults[locationThree].DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
const holeThree = objThree ? objThree.Value : 'Not Found';
I want to make code more efficient and readable
You are always using the same pattern (changing parts written in ALL_UPPERCASE):
var boreholeOne = logReportDataQryResults[ LOCATION ].Id;
const objOne = logReportDataQryResults[ LOCATION ].DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
const holeOne = objOne ? objOne.Value : 'Not Found';
You can encapsulate it in a function and pass the changing parts into it:
const getBoreholeValue = (locationId, data) => {
const id = data[locationId].Id;
const obj = data[locationId].DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
return obj ? obj.Value : 'Not Found';
}
And then use it like this:
const res1 = getBoreholeValue(0, logReportDataQryResults);
const res2 = getBoreholeValue(1, logReportDataQryResults);
const res3 = getBoreholeValue(2, logReportDataQryResults);
Example:
const respBody = [
{
"Id": "ae61098c-eb7c-4ee8-aca7-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH127"
}
],
},
{
"Id": "84cd9a9f-d085-4642-b484-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH128"
}
],
},
{
"Id": "6629d92b-1dcf-4fc1-a019-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH129"
}
],
},
{
"Id": "47442b4f-f691-4213-b705-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH130"
}
],
}
]
const getBoreholeValue = (locationId, data) => {
const id = data[locationId].Id;
const obj = data[locationId].DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
return obj ? obj.Value : 'Not Found';
}
console.log(getBoreholeValue(0, respBody));
console.log(getBoreholeValue(1, respBody));
console.log(getBoreholeValue(2, respBody));
You might use a single object instead of lots of separate variables - use .map to iterate over the locations and construct a new array with the info you need:
const logReportDataQryResults = [
{
"Id": "ae61098c-eb7c-4ee8-aca7-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH127"
}
],
},
{
"Id": "84cd9a9f-d085-4642-b484-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH128"
}
],
},
{
"Id": "6629d92b-1dcf-4fc1-a019-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH129"
}
],
},
{
"Id": "47442b4f-f691-4213-b705-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH130"
}
],
}
]
const locations = [0, 1, 2];
const boreholes = locations.map((location) => {
const { Id, DataFields } = logReportDataQryResults[location];
const obj = DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
const holeValue = obj ? obj.Value : 'Not Found';
return { Id, obj, holeValue };
});
console.log(boreholes);
var logReportDataQryResults =
[
{
"Id": "ae61098c-eb7c-4ee8-aca7-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH127"
}
],
},
{
"Id": "84cd9a9f-d085-4642-b484-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH128"
}
],
},
{
"Id": "6629d92b-1dcf-4fc1-a019-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH129"
}
],
},
{
"Id": "47442b4f-f691-4213-b705-aa080112d656",
"DataFields": [
{
"Header": "LocationDetails.LocationID",
"Value": "BH130"
}
],
}
]
const boreholes=[];
for (key in logReportDataQryResults) {
const { Id, DataFields } = logReportDataQryResults[key];
const obj = DataFields.find(({ Header }) => Header == 'LocationDetails.LocationID');
const holeValue = obj ? obj.Value : 'Not Found';
boreholes.push({ "Id": Id,"holeValue": holeValue });
}
console.log(boreholes)

change value of an array of nested objects to a string

this is the array that i currently have
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
I want to map over each nested object inside the array so that the value of each nested object is the value property of that object as a string. so the object would become:
const myArr = [
{
"code": "AC16",
"convictionDate":"2019-03-07"
},
{
"code":"AC20",
"convictionDate": "2019-03-06"
}
]
Ive tried this with no success:
const x = myArr.map((item)=>{
console.log(item)
Object.keys(item).map(function(key,i) {
item[key] = item[key][value];
})
})
You are almost there. Just use array map
const myArr = [{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
let newArray = myArr.map(function(item) {
return {
code: item.code.value,
convictionDate: item.convictionDate.value
}
});
console.log(newArray)
Map the array, and reduce the entries to the required object form:
const myArr = [{"code":{"value":"AC16","description":"text"},"convictionDate":{"value":"2019-03-07"}},{"code":{"value":"AC20","description":"text"},"convictionDate":{"value":"2019-03-06"}}];
const result = myArr.map(o =>
Object.entries(o).reduce((r, [k, { value }]) => ({ ...r, [k]: value }), {})
);
console.log(result);
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
let newArray = myArr.map(e => {
return { "code":e.code.value, "convictionDate": e.convictionDate.value}
})
console.log(newArray);
It goes without saying there is some awesome reference material over at W3 Schools, the provide good detail on this in their article here
That said...
Why not simplify the code a little and try this against your array:-
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
// PROPOSED SOLUTION CODE
const x = myArr.map((item)=>{
return {code: item.code.value,convictionDate: item.convictionDate.value}
});
// Your Desired Example Provided in Question
const xArr = [
{
"code": "AC16",
"convictionDate":"2019-03-07"
},
{
"code":"AC20",
"convictionDate": "2019-03-06"
}
];
// Output Validation
console.log('Response of Array \'x\'');
console.log(x);
console.log('Your Desired Example');
console.log(xArr);
When using 'map'; we must map the source array ('myArr') to our new target array ('x').
In the context of the example code you have provided, 'data.convictions' is undefined.
The magic is all here:-
const x = myArr.map((item)=>{
return {code: item.code.value,convictionDate: item.convictionDate.value}
});
Happy coding!

Categories