I have an array called this.loanAdjustmentList that I am adding data to but it is showing as empty when I need it. I call a service that returns a response to this.loanAdjustmentResult. I have showed response result below.
response
this.loanAdjustmentResult = [
{
"newCalculatedInstalmentsNo": "41",
"newContractEndDate": "20241016",
"newResidual": "35628.23",
"newInstalment": "3867.45",
"newTerm": "59",
"outBalanceAvaf": null,
"restructureType": "term"
},
{
"newCalculatedInstalmentsNo": "54",
"newContractEndDate": "20251116",
"newResidual": "35628.23",
"newInstalment": "3128.39",
"newTerm": "72",
"outBalanceAvaf": null,
"restructureType": "instalment"
},
{
"newCalculatedInstalmentsNo": "54",
"newContractEndDate": "20251116",
"newResidual": "0",
"newInstalment": "3867.45",
"newTerm": "72",
"outBalanceAvaf": null,
"restructureType": "balloon"
}
]
method
doLoanAdjustmentOptions() {
this.loanAdjustmentList = [];
this.subs = this.avafService.confirmData.subscribe((resp) => {
this.loanAdjustmentResult = resp.calculateAVAFLoanAdjustment.calculatorResults.calculatorResult;
//search loanAdjustmentResult for which restructure types are allowed in order to set relevent radio button options
for (let i = 0; i < this.loanAdjustmentResult.length; i++) {
if (this.loanAdjustmentResult[i].restructureAllowed == "Y") {
if (this.loanAdjustmentResult[i].restructureType == "balloon") {
this.loanAdjustmentList.push({
label: this.translations["balloon"],
subLabel: this.translations["balloonDescription"],
name: this.loanAdjustmentResult[i].restructureType,
checked: this.setupForm.value['reduceoptionRadio'] === 'balloon'
});
console.log(this.loanAdjustmentList);
}
if (this.loanAdjustmentResult[i].restructureType == "term") {
this.loanAdjustmentList.push({
label: this.translations["term"],
subLabel: this.translations["termDescription"],
name: this.loanAdjustmentResult[i].restructureType,
checked: this.setupForm.value['reduceoptionRadio'] === 'term'
});
}
if ( this.loanAdjustmentResult[i].restructureType == "instalment") {
this.loanAdjustmentList.push({
label: this.translations["install"],
subLabel: this.translations["installDescription"],
name: this.loanAdjustmentResult[i].restructureType,
checked: this.setupForm.value['reduceoptionRadio'] === 'instalment'
});
}
}
}
console.log(this.loanAdjustmentList);
Object.keys(this.loanAdjustmentResult).forEach((key) => {
this.calculatorResult = this.loanAdjustmentResult[key];
//assign calculator new residual value to radio button option labels
for (let i = 0; i < this.calculatorResult.length; i++) {
if (this.calculatorResult[i].restructureType == "balloon") {
const newResidual = this.calculatorResult[i].newResidual;
let objIndex = this.loanAdjustmentList.findIndex((obj => obj.name == 'balloon'));
this.loanAdjustmentList[objIndex].label = this.translations["balloon"] + " " + this.utils.convertNumberToCurrency(newResidual);
}
if (this.calculatorResult[i].restructureType == "term") {
const newTerm = this.calculatorResult[i].newTerm;
let objIndex = this.loanAdjustmentList.findIndex((obj => obj.name == 'term'));
this.loanAdjustmentList[objIndex].label = this.translations["term"] + " " + newTerm + " " + this.translations["monthsLowerCase"];
}
if (this.calculatorResult[i].restructureType == "instalment") {
const newInstalment = this.calculatorResult[i].newInstalment;
let objIndex = this.loanAdjustmentList.findIndex((obj => obj.name == 'instalment'));
this.loanAdjustmentList[objIndex].label = this.translations["install"] + " " + this.utils.convertNumberToCurrency(newInstalment);
};
this.showFormData = true;
}
});
})
}
My issue is that this.loanAdjustmentList is showing as empty. I'm not sure if the values are being set quick enough to the array so that when I want to use it in the Object.keys sub-method, it is available. Any idea?
It's because of you have checked your first condition is
if (this.loanAdjustmentResult[i].restructureAllowed == "Y") {}
But you have not received restructureAllowed this key in your this.loanAdjustmentResult variable data.
Related
Trying to derive Full JPATH if Object is an Array.
Running below code,
var INPUT = ['ADDR.ADDR_L1','NAME.FIRST_NAME','CONTACT.TYPE','LEVEL1OBJ.LEVEL2OBJ','LEVEL1OBJ.LEVEL2ARR.LEVEL3OBJ'];
var obj = {
"ID":"1",
"NAME":{"FIRST_NAME":"ABC","LAST_NAME":"XYZ"},
"ADDR":
[{"TYPE":"HOME",
"ADDR_L1":"SDGSG",
"CITY":"AFAFA"},
{"TYPE":"OFFC",
"ADDR_L1":"AFASF",
"CITY":"SDGSDG"}],
"CONTACT":
[{"TYPE":"A"},{"TYPE":"B"},{"TYPE":"C"}],
"LEVEL1OBJ":{"LEVEL2ARR":[
{"LEVEL3OBJ":"A"},
{"LEVEL3OBJ":"B"}],
"LEVEL2OBJ":"GFDB"
}
};
var jpath1=[];
var jpath_final=[];
for ( var i=0;i<INPUT.length;i++)
{ // Loop over the list of JPATH coming in as INPUT
jpath1=[];
console.log("I"+i);
var jpath = INPUT[i].split('.'); //Splitting keys in an array
console.log(jpath);
for ( var j=0;j<jpath.length;j++)
{ //loop over all keys in input
console.log("J"+j);
var subjpath=jpath[j];
console.log(jpath.length);
console.log(subjpath);
for ( var key of Object.keys(obj) ) //getting all keys on obj
{
console.log("KEY");
console.log(key);
if ( Object.prototype.toString.call(obj[key]) === '[object Array]' && subjpath == key ) //if object is an array
{
console.log("yes");
console.log(obj[key].length);
for ( var k=0;k<obj[key].length;k++)
{ //looping over all array index
console.log("k"+k);
jpath1.push(subjpath+'.'+k); //appending array index to original jpath
console.log(jpath1);
}
}
else if ( key == subjpath )
{
jpath1.push(subjpath);
subjpath="";
}
}
}
//appending other objects after array object
jpath1.forEach((element, index) => {
jpath1[index] = element + '.' + subjpath;
});
console.log(jpath1);
jpath_final.push(jpath1);
console.log(jpath_final);
}
Current Output:
[
[ 'ADDR.0.ADDR_L1', 'ADDR.1.ADDR_L1' ],
[ 'NAME.FIRST_NAME' ],
[ 'CONTACT.0.TYPE', 'CONTACT.1.TYPE', 'CONTACT.2.TYPE' ],
[ 'LEVEL1OBJ.LEVEL2OBJ' ],
[ 'LEVEL1OBJ.LEVEL3OBJ' ] --Incorrect
]
The process is working for scenario where Array Object is first level. But not working for 2nd Level onwards array object. I know i need to perform it recursively but corrupting the result if I take out Object.keys loop as function.
Expected Output
[
[ 'ADDR.0.ADDR_L1', 'ADDR.1.ADDR_L1' ],
[ 'NAME.FIRST_NAME' ],
[ 'CONTACT.0.TYPE', 'CONTACT.1.TYPE', 'CONTACT.2.TYPE' ],
[ 'LEVEL1OBJ.LEVEL2OBJ' ],
[ 'LEVEL1OBJ.LEVEL2ARR.0.LEVEL3OBJ' ,'LEVEL1OBJ.LEVEL2ARR.1.LEVEL3OBJ' ]
]
Meanwhile I tried something more which gives close to what i needed,
var INPUT = ['ADDR.ADDR_L1','NAME.FIRST_NAME','CONTACT.TYPE','LEVEL1OBJ.LEVEL2OBJ','LEVEL1OBJ.LEVEL2ARR.LEVEL3OBJ'];
var obj = {
"ID":"1",
"NAME":{"FIRST_NAME":"ABC","LAST_NAME":"XYZ"},
"ADDR":
[{"TYPE":"HOME",
"ADDR_L1":"SDGSG",
"CITY":"AFAFA"},
{"TYPE":"OFFC",
"ADDR_L1":"AFASF",
"CITY":"SDGSDG"}],
"CONTACT":
[{"TYPE":"A"},{"TYPE":"B"},{"TYPE":"C"}],
"LEVEL1OBJ":{"LEVEL2ARR":[
{"LEVEL3OBJ":"A"},
{"LEVEL3OBJ":"B"}],
"LEVEL2OBJ":"GFDB"
}
};
var jpath_final=[];
function append_index(jp,index)
{
if ( jpath_final[i] == null )
{
jpath_final[i] = jp+'.'+index;
}
else
{
jpath_final[i] += '.'+jp+'.'+index;
}
return;
}
function append_jpath(jp)
{
if ( jpath_final[i] == null )
{
jpath_final[i] = jp;
}
else
{
jpath_final[i] += '.'+jp;
}
return;
}
function chk_func ( obj,jpath )
{
for ( var key of Object.keys(obj) )
{
console.log("Print Key:"+key);
console.log("JPATH "+jpath);
console.log("J " + j);
if ( j == jpath.length-1 )
{
console.log("Enter 1st if");
append_jpath(jpath[j]);
j++;
console.log("JPATH "+ jpath_final[i]);
return;
}
else
{
if ( typeof obj[key] == 'object' && key == jpath[j] && Object.prototype.toString.call(obj[key]) != "[object Array]")
{
console.log("Enter 2nd if");
console.log( jpath[j] + " is Object");
append_jpath(jpath[j]);
console.log( "JPATH "+jpath_final[i]);
j++;
console.log("Now Object "+ key+" "+jpath[j] );
chk_func(obj[key],jpath);
break;
}
else if ( Object.prototype.toString.call(obj[key]) === "[object Array]" && key == jpath[j] )
{
console.log("Enter 3rd if");
console.log("jpath "+jpath);
console.log("key "+key);
console.log(jpath[j] + " is Array");
append_index(jpath[j],obj[key].length);
console.log("JPATH "+jpath_final[i]);
return;
}
else
{
continue;
}
}
}
return;
}
for ( var i=0;i<INPUT.length;i++)
{
console.log("i:"+i);
var jpath = INPUT[i].split('.');
console.log(jpath);
for ( var j=0;j<jpath.length;j++)
{
console.log("j:"+j);
console.log(jpath[j]);
if ( j < jpath.length-1 && jpath[j] != undefined )
{
chk_func(obj,jpath);
}
else
{
append_jpath(jpath[j]);
console.log("JPATH "+ jpath_final[i]);
}
}
}
console.log("final "+jpath_final);
I think the entry point of your recursion is likely where you are stumbling. If you'll move all of your processing into the recursive block, then you can process from a top-down approach in your object. This also allows you to peel off layers of the object for processing as you navigate through the split path (INPUT array).
There are a few other changes in the following to be a little more efficient, and I changed a few variable names to help me keep things straight as I was debugging.
var INPUT = [ "ADDR.ADDR_L1", "NAME.FIRST_NAME", "CONTACT.TYPE", "LEVEL1OBJ.LEVEL2OBJ", "LEVEL1OBJ.LEVEL2ARR.LEVEL3OBJ"];
var main_obj = {
ID: "1",
NAME: { FIRST_NAME: "ABC", LAST_NAME: "XYZ" },
ADDR: [
{ TYPE: "HOME", ADDR_L1: "SDGSG", CITY: "AFAFA" },
{ TYPE: "OFFC", ADDR_L1: "AFASF", CITY: "SDGSDG" }
],
CONTACT: [{ TYPE: "A" }, { TYPE: "B" }, { TYPE: "C" }],
LEVEL1OBJ: {
LEVEL2ARR: [{ LEVEL3OBJ: "A" }, { LEVEL3OBJ: "B" }],
LEVEL2OBJ: "GFDB"
}
};
var json_final = [];
for (var keyInput of INPUT) {
processKeys(keyInput, main_obj, keyInput);
}
console.log(JSON.stringify(json_final));
function processKeys (keyInp, obj, rootKeyInp) {
if (keyInp.includes('.')) {
var tokens = keyInp.split('.');
if (1 < tokens.length) {
console.log(tokens[0] + ' :: ' + rootKeyInp);
var keyInp0 = tokens.shift();
if (obj[keyInp0] != null) {
processKeys(tokens.join('.'), obj[keyInp0], rootKeyInp);
}
}
} else {
var json_arr_tmp = [];
if (Object.prototype.toString.call(obj) === "[object Array]") {
for (var i = 0; i < obj.length; i++) {
let rootKeyInpSuffix = rootKeyInp.slice(-(keyInp.length + 1));
json_arr_tmp.push(rootKeyInp.substr(0, rootKeyInp.lastIndexOf(rootKeyInpSuffix)) + '.' + i + rootKeyInpSuffix);
}
} else {
json_arr_tmp.push(rootKeyInp);
}
json_final.push(json_arr_tmp);
}
}
I'm creating a map based on this example:
https://labs.mapbox.com/education/impact-tools/finder-with-filters/
In their example, they have two dropdown filters and one checkbox filter. I would like to have three checkbox filters. I created three checkbox filters, and on their own, they seem to work well. The issue is that the filters seem to override each other in the order clicked. In their example, the filters seem to be working together, so I can't figure out why it's not working anymore when I changed the filter type.
Here's the code for my project:
https://codepen.io/flyinginsect2/pen/eYdyqxZ
Here are snippets of the code relevant to filtering:
const config = {
style: "mapbox://styles/mapbox/light-v10",
accessToken: "pk.eyJ1IjoibGF1cmFqZWFudGhvcm5lIiwiYSI6ImNraXl5M29oMDEyMjgzM3BhNTh1MGc1NjkifQ.g4IAFIrXPpl3ricw3f_Onw",
CSV: "https://docs.google.com/spreadsheets/d/106xm254us29hAUEtR7mTo0hwbDJv8dhyQs9rxY601Oc/gviz/tq?tqx=out:csv&sheet=Attributes",
center: [-104.339, 46.869],
zoom: 2,
title: "ENVIROlocity Mapper",
description: "Environmental Networking, Volunteering, Internship, and R.... Opportunities",
sideBarInfo: ["Org_name", "CityState"],
popupInfo: ["Org_name"],
filters: [
{
type: "checkbox",
title: "Sector: ",
columnHeader: "Sector",
listItems: ["Local Government", "Nonprofit"]
},
{
type: "checkbox",
title: "Industry: ",
columnHeader: "Industry_type",
listItems: ["Conservation", "Policy"]
},
{
type: "checkbox",
title: "Internships: ",
columnHeader: "internships_YN",
listItems: ["Yes"]
}
]
};
const selectFilters = [];
const checkboxFilters = [];
function createFilterObject(filterSettings) {
filterSettings.forEach(function (filter) {
if (filter.type === 'checkbox') {
columnHeader = filter.columnHeader;
listItems = filter.listItems;
const keyValues = {};
Object.assign(keyValues, { header: columnHeader, value: listItems });
checkboxFilters.push(keyValues);
}
if (filter.type === 'dropdown') {
columnHeader = filter.columnHeader;
listItems = filter.listItems;
const keyValues = {};
Object.assign(keyValues, { header: columnHeader, value: listItems });
selectFilters.push(keyValues);
}
});
}
function applyFilters() {
const filterForm = document.getElementById('filters');
filterForm.addEventListener('change', function () {
const filterOptionHTML = this.getElementsByClassName('filter-option');
const filterOption = [].slice.call(filterOptionHTML);
const geojSelectFilters = [];
const geojCheckboxFilters = [];
filteredFeatures = [];
filteredGeojson.features = [];
filterOption.forEach(function (filter) {
if (filter.type === 'checkbox' && filter.checked) {
checkboxFilters.forEach(function (objs) {
Object.entries(objs).forEach(function ([key, value]) {
if (value.includes(filter.value)) {
const geojFilter = [objs.header, filter.value];
geojCheckboxFilters.push(geojFilter);
}
});
});
}
if (filter.type === 'select-one' && filter.value) {
selectFilters.forEach(function (objs) {
Object.entries(objs).forEach(function ([key, value]) {
if (value.includes(filter.value)) {
const geojFilter = [objs.header, filter.value];
geojSelectFilters.push(geojFilter);
}
});
});
}
});
if (geojCheckboxFilters.length === 0 && geojSelectFilters.length === 0) {
geojsonData.features.forEach(function (feature) {
filteredGeojson.features.push(feature);
});
} else if (geojCheckboxFilters.length > 0) {
geojCheckboxFilters.forEach(function (filter) {
geojsonData.features.forEach(function (feature) {
if (feature.properties[filter[0]].includes(filter[1])) {
if (
filteredGeojson.features.filter(
(f) => f.properties.id === feature.properties.id
).length === 0
) {
filteredGeojson.features.push(feature);
}
}
});
});
if (geojSelectFilters.length > 0) {
const removeIds = [];
filteredGeojson.features.forEach(function (feature) {
let selected = true;
geojSelectFilters.forEach(function (filter) {
if (
feature.properties[filter[0]].indexOf(filter[1]) < 0 &&
selected === true
) {
selected = false;
removeIds.push(feature.properties.id);
} else if (selected === false) {
removeIds.push(feature.properties.id);
}
});
});
removeIds.forEach(function (id) {
const idx = filteredGeojson.features.findIndex(
(f) => f.properties.id === id
);
filteredGeojson.features.splice(idx, 1);
});
}
} else {
geojsonData.features.forEach(function (feature) {
let selected = true;
geojSelectFilters.forEach(function (filter) {
if (
!feature.properties[filter[0]].includes(filter[1]) &&
selected === true
) {
selected = false;
}
});
if (
selected === true &&
filteredGeojson.features.filter(
(f) => f.properties.id === feature.properties.id
).length === 0
) {
filteredGeojson.features.push(feature);
}
});
}
map.getSource('locationData').setData(filteredGeojson);
buildLocationList(filteredGeojson);
});
}
function filters(filterSettings) {
filterSettings.forEach(function (filter) {
if (filter.type === 'checkbox') {
buildCheckbox(filter.title, filter.listItems);
} else if (filter.type === 'dropdown') {
buildDropDownList(filter.title, filter.listItems);
}
});
}
function removeFilters() {
let input = document.getElementsByTagName('input');
let select = document.getElementsByTagName('select');
let selectOption = [].slice.call(select);
let checkboxOption = [].slice.call(input);
filteredGeojson.features = [];
checkboxOption.forEach(function (checkbox) {
if (checkbox.type == 'checkbox' && checkbox.checked == true) {
checkbox.checked = false;
}
});
selectOption.forEach(function (option) {
option.selectedIndex = 0;
});
map.getSource('locationData').setData(geojsonData);
buildLocationList(geojsonData);
}
function removeFiltersButton() {
const removeFilter = document.getElementById('removeFilters');
removeFilter.addEventListener('click', function () {
removeFilters();
});
}
createFilterObject(config.filters);
applyFilters();
filters(config.filters);
removeFiltersButton();
I read this Mapbox documentation on combining filters, but I can't figure out how to work it in.
https://docs.mapbox.com/mapbox-gl-js/style-spec/other/#other-filter
I know there are many other Stack Exchange posts out there that address filtering on multiple criteria, but I can't find one that seems to address this specific issue.
The issue is in the space in value for "Local Government"
If you look at the generated HTML you will see a space in the id, which is not valid HTML
<input class="px12 filter-option" type="checkbox" id="Local Government" value="Local Government">
Just remove the whitespaces when building the HTML id attribute
input.setAttribute('id', listItems[i].replace(/\s/g,''));
genderPie()
let filter = {};
async function genderPie() {
const d = await getData();
const g = await d.reduce((a, o) => (o.GEN && a.push(o.GEN), a), []);
const gender = Object.keys(g).length;
const m = await d.reduce((a, o) => (o.GEN == 1 && a.push(o.GEN), a), []);
const male = Object.keys(m).length;
const f = await d.reduce((a, o) => (o.GEN == 2 && a.push(o.GEN), a), []);
const female = Object.keys(f).length;
var data = [{
name: 'male',
y: male,
id: 1
}, {
name: 'female',
y: female,
id: 2
}];
chart = new Highcharts.Chart({
plotOptions: {
pie: {
innerSize: '80%',
dataLabels: {
connectorWidth: 0
}
}
},
series: [{
"data": data,
type: 'pie',
animation: false,
point: {
events: {
click: function(event) {
filter.GEN = '' + this.id + '';
}
}
}
}],
"chart": {
"renderTo": "gender"
},
});
}
async function getData() {
buildFilter = (filter) => {
let query = {};
for (let keys in filter) {
if (filter[keys].constructor === Array && filter[keys].length > 0) {
query[keys] = filter[keys];
}
}
return query;
}
//FILTER DATA
//Returns the filtered data
filterData = (dataset, query) => {
const filteredData = dataset.filter((item) => {
for (let key in query) {
if (item[key] === undefined || !query[key].includes(item[key])) {
return false;
}
}
return true;
});
return filteredData;
};
//FETCH JSON
const dataset = [{
"GEN": "2"
}, {
"GEN": "1"
}, {
"GEN": "1"
}, {
"GEN": "2"
},
{
"GEN": "2"
}, {
"GEN": "2"
}, {
"GEN": "2"
}, {
"GEN": "1"
}
]
//BUILD THE FILTER
const query = buildFilter(filter);
const result = filterData(dataset, query);
console.log(result)
return result
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="gender"></div>
does anyone can explain me how to handle the following?
I have two functions that filter data and than I build a chart with Hichart
Each time a user click for example a slice of a pie chart an event is fired and an object is populated.
That object allows me to filter the dataset and redraw the chart
The last thing I'm missing is about to update the filtering functions based on the object to be populated
first I'll do this
async function getData() {
buildFilter = (filter) => {
let query = {};
for (let keys in filter) {
if (filter[keys].constructor === Array && filter[keys].length > 0) {
query[keys] = filter[keys];
}
}
return query;
}
then
filterData = (data, query) => {
const filteredData = data.filter( (item) => {
for (let key in query) {
if (item[key] === undefined || !query[key].includes(item[key])) {
return false;
}
}
return true;
});
return filteredData;
};
const query = buildFilter(filter);
const result = filterData(data, query);
my object is
let filter = {}
when a user click the slice myobject become for example
let filter = {
gen: "1"
}
Take a look at this StackBlitz project.
In getData(), I simplified your filter to this one:
return data.filter(item => {
for (const property of Object.keys(filter)) {
if (item[property] !== filter[property]) {
return false;
}
}
return true;
});
and when a slice is clicked, I call genderPie() again, after updating the filter.
You might want to separate the data request from the filtering, so that the data is downloaded only once, not every time a filter is changed.
Hello I'm new in JS and I need to test the if.
const length = notifications.length
notifications.forEach((notification, index) => {
if (length > 1 && index < length - 1) {
toolTipText += ' '
}
In other words I need to declare a variable to enter the if. I have these variable but is wrong and I don't know how to do it well
const mockPropsForComponentAlternatorAndLOW = {
notifications: [{
params: {
subType: 'ALTERNATOR'
}
},
params: {
subType: 'LOW'
}]
}
Any suggestions?
Your script works. Just remove some syntax mistakes and point to the right reference:
mockPropsForComponentAlternatorAndLOW.notifications.length
const mockPropsForComponentAlternatorAndLOW = {
notifications: [
{
params: {
subType: 'ALTERNATOR'
}
},
{
params: {
subType: 'LOW'
}
}
]
}
const length = mockPropsForComponentAlternatorAndLOW.notifications.length
mockPropsForComponentAlternatorAndLOW.notifications.forEach((notification, index) => {
if (length > 1 && index < length - 1) {
alert('in the scope now')
// toolTipText += ' '
}
})
I'm not 100% sure what you're asking, but I'm going to interpret this as "my code isn't running, what's wrong with it?". There's a syntax error in your mockPropsForComponentAlternatorAndLOW variable. There needs to be a "{" and "}" around the second "notification" object, like this:
const mockPropsForComponentAlternatorAndLOW = {
notifications: [{
params: {
subType: 'ALTERNATOR'
}
},
{
params: {
subType: 'LOW'
}
}]
}
Your question is fairly vague, but if I assume you're building toolTipText by appending notification text and you want a space between each notification text, the minimal change would be to test index > 0 && index < length rather than length > 1 && index < length - 1:
let toolTipText = "";
const length = notifications.length;
notifications.forEach((notification, index) => {
if (index > 0 && index < length) {
toolTipText += ' '
}
toolTipText += notification.text; // Or whatever the property is called
});
Live Example:
function buildToolTipText(notifications) {
let toolTipText = "";
const length = notifications.length;
notifications.forEach((notification, index) => {
if (index > 0 && index < length) {
toolTipText += ' '
}
toolTipText += notification.text; // Or whatever the property is called
});
return toolTipText;
}
console.log(buildToolTipText([{text: "only"}]));
console.log(buildToolTipText([{text: "first"}, {text: "second"}]));
console.log(buildToolTipText([{text: "first"}, {text: "second"}, {text: "third"}]));
but, you may find it simpler to use map and join:
let toolTipText = notifications.map(n => n.text).join(" ");
Live Example:
function buildToolTipText(notifications) {
let toolTipText = notifications.map(n => n.text).join(" ");
return toolTipText;
}
console.log(buildToolTipText([{text: "only"}]));
console.log(buildToolTipText([{text: "first"}, {text: "second"}]));
console.log(buildToolTipText([{text: "first"}, {text: "second"}, {text: "third"}]));
I'm trying to drill down to the bottom of this JSON object and find the medication.
This is the JSON
const initialState = {
medicationschedule: [
{
date: '2019-08-29',
medications: [
{
title: '8.00 AM',
id:'1111',
data: [
{name:'item1', isTaken: 1,mg: '500 mg',capsules:'capsule'},
{name:'item2', isTaken: 4,mg: '2000 mg',capsules:'teaspoon'}
]},
{
title: '12.03 PM',
id:'11112',
data: [
{name:'item3', isTaken: 2,mg: '500 mg',capsules:'capsule'},
{name:'item4', isTaken: 1,mg: '500 mg',capsules:'capsule'}
]},
{
title: '3.30 PM',
id:'11113',
data: [
{name:'item1', isTaken: 3,mg: '500 mg',capsules:'capsule'}
]},
]
},
{
date: '2019-08-26',
medications: [
{
title: '8.00 AM',
id:'11151',
data: [
{name:'item1', isTaken: 1,mg: '500 mg',capsules:'capsule'},
{name:'item2', isTaken: 4,mg: '2000 mg',capsules:'teaspoon'}
]},
]
}
],
selectedDate: Date()
};
Now I'm using the following function to drill down this object. The function is given below.
getMedicationDetail = (medName, groupId) => {
console.log(medName + " " + groupId + " " + convertedDateString(this.props.selectedDate));
console.log(typeof(Number(groupId).toString()))
this.props.medicationschedule.forEach(schedule=>{
if (schedule.date === convertedDateString(this.props.selectedDate)) {
schedule.medications.forEach(medicationsT =>{
if (medicationsT.id === groupId) {
return medicationsT.data.forEach(medicine => {
if( medicine.name === medName ) {
console.log(medicine)
return medicine
}
})
}
})
}
});
}
The problem is function always returns empty array []. But the line console.log(medicine) actually prints the value I want. What could be the root cause of it?
You are only returning from the inner callback function of the forEach loop, not returning from the getMedicationDetail function.
Try something like:
getMedicationDetail = (medName, groupId) => {
console.log(medName + " " + groupId + " " + convertedDateString(this.props.selectedDate));
console.log(typeof(Number(groupId).toString()))
let foundMedicine;
this.props.medicationschedule.forEach(schedule=>{
if (schedule.date === convertedDateString(this.props.selectedDate)) {
schedule.medications.forEach(medicationsT =>{
if (medicationsT.id === groupId) {
medicationsT.data.forEach(medicine => {
if( medicine.name === medName ) {
console.log(medicine)
foundMedicine = medicine;
}
})
}
})
}
});
return foundMedicine;
}
You got empty array because forEach won't receive return value. you should use map instead of forEach if u hope to get return value.
// This is wrong, use map instead
schedule.medications.forEach(medicationsT =>{
if (medicationsT.id === groupId) {
return medicationsT.data.forEach(medicine => {
if( medicine.name === medName ) {
console.log(medicine)
return medicine
}
})
}
})
and i am trying to provide better solution by avoiding the inner loops as much as possible because O3, here is my best answer at least it is avoid the O3 problems:
const getMedicationsByDate = initialState.medicationschedule.reduce((prevVal, schedule) => {
if (schedule.date === "2019-08-29") prevVal.push(schedule.medications)
return prevVal
}, []).flat(1)
// Get the medicine data only
const getMedicineDataByGroupIdAndName = getMedicationsByDate.reduce((prevVal, medications) => {
if (medications.id === '11111') {
const getData = medications.data.filter(({ name }) => name === 'item1')
prevVal.push(getData)
}
return prevVal
},[]).flat(1)
// Get the whole tree of medications object except date
const getWholeMedicationTreeByDate = getMedicationsByDate.map(medication => {
if (medication.id === '11111') {
let medic = medication
medic.data = medication.data.filter(({ name }) => name === 'item1')
return medic
}
}).filter(medic => medic)
Just push medicine in the array,
getMedicationDetail = (medName, groupId) => {
console.log(medName + " " + groupId + " " + convertedDateString(this.props.selectedDate));
console.log(typeof(Number(groupId).toString()));
const medicineList=[];
this.props.medicationschedule.forEach(schedule=>{
if (schedule.date === convertedDateString(this.props.selectedDate)) {
schedule.medications.forEach(medicationsT =>{
if (medicationsT.id === groupId) {
medicationsT.data.forEach(medicine => {
if( medicine.name === medName ) {
console.log(medicine)
medicinelist.push(medicine);
}
})
}
})
}
});
return medicineList;
}
This will return a medicineList. Hope this can help!