How can I access to the if with an array of objects? - javascript

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

Related

MongoDB if statement in a parameter

I am trying to not make my code redundant and I would like to know, if in a .updateOne method, when Im passing data to change, if its possible to implement if statement to choose from the data. Here is a situation.
I have my db model:
const depositarySchema = new Schema({
euid: {
type: String,
required: true
},
euid2: {
type: String
},
count: {
type: Number,
required: true
},
euroPallets: {
type: Number,
},
biggerPallets: {
type: Number,
},
otherPallets: {
type: Number,
},
depositary: {
type: Number,
required: true
},
title: {
type: String
}
});
Then I have a variable: var = 1 for euroPallets, 2 for biggerPallets and 3 for otherPallets. I would like to implement something like this:
Depositary.updateOne(
{
euid: euid,
},
{
count: dep.count - palletCounter,
if(var === 1){
euroPallets: count}
elseif(var===2){
biggerPallets: count}
else{
otherPallets: count}
},
where count is just a number. I hope its understandable what im trying to achieve, sorry for a wrong syntax.
Wernfried Domscheit beat me to it, but I will post my answer anyways.
const palletTypes = ['otherPallets', 'euroPallets', 'biggerPallets'];
var count = ep.count - palletCounter;
var palletType = palletTypes[count] || palletTypes[0];
var pallets = {'count': count};
pallets[palletType] = count;
Depositary.updateOne(
{euid: euid},
pallets
)
I would honestly just make a helper method so you can just send in parameters and it will turn everything to the correct objects.
updatePallets(euid, ep.count, palletCounter)
Maybe this one:
let upd = {
euid: euid,
count: dep.count - palletCounter
};
if (var === 1) {
upd['euroPallets'] = count;
}
else if (var === 2) {
upd['biggerPallets'] = count;
}
else {
upd['otherPallets'] = count;
}
Depositary.updateOne(upd)
EDIT:
For .updateOne() method to actually work like I want to, you need to separate the euid parameter. The correct solution is this:
let upd = {
count: dep.count - palletCounter
};
if (var === 1) {
upd['euroPallets'] = count;
}
else if (var === 2) {
upd['biggerPallets'] = count;
}
else {
upd['otherPallets'] = count;
}
Depositary.updateOne(
{
euid: euid,
},
upd,
)

Empty array despite pushing data to it

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.

How can I check if the array of objects have all values duplicate?

var values = [
{ name: 'Car',Data:'Required',value:'Vehicle' },
{ name: 'Auto',Data:'Required',value:'Vehicle'},
{ name: 'Bike',Data:'Required',value:'Vehicle'},
{ name: 'Car',Data:'Required',value:'Vehicle' }
];
Duplicate object will be:
{ name: 'Car',Data:'Required',value:'Vehicle' }
You can check if an array contains the same item on a different index and by that, understand that there is a duplicate:
const values = [
{ name: 'Car',Data:'Required',value:'Vehicle' },
{ name: 'Auto',Data:'Required',value:'Vehicle'},
{ name: 'Bike',Data:'Required',value:'Vehicle'},
{ name: 'Car',Data:'Required',value:'Vehicle' }
];
const duplicates = values.filter((item, idx) => values.findIndex(i => item.name === i.name && item.Data === i.Data && item.value === i.value) !== idx);
console.log(duplicates);
If you want to check all the properties of objects, you have to introduce a new function, and use it to filter your array:
var values = [
{ name: 'Car',Data:'Required',value:'Vehicle' },
{ name: 'Auto',Data:'Required',value:'Vehicle'},
{ name: 'Bike',Data:'Required',value:'Vehicle'},
{ name: 'Bike',Data:'Required',value:'Different VL'},
{ name: 'Car',Data:'Required',value:'Vehicle' }
];
Object.compare = function (obj1, obj2) {
//Loop through properties in object 1
for (var p in obj1) {
//Check property exists on both objects
if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) return false;
switch (typeof (obj1[p])) {
//Deep compare objects
case 'object':
if (!Object.compare(obj1[p], obj2[p])) return false;
break;
//Compare function code
case 'function':
if (typeof (obj2[p]) == 'undefined' || (p != 'compare' && obj1[p].toString() != obj2[p].toString())) return false;
break;
//Compare values
default:
if (obj1[p] != obj2[p]) return false;
}
}
//Check object 2 for any extra properties
for (var p in obj2) {
if (typeof (obj1[p]) == 'undefined') return false;
}
return true;
};
var doubles = values.filter((x,i,a) =>a.slice(0,i).find(y=>Object.compare(x,y)))
console.log(doubles)
Working ahead from the answer in:
https://stackoverflow.com/a/840808/11057988
var findDuplicates = (arr) => {
let sorted_arr = arr.slice().sort(sortFunc); // You can define the comparing function here.
// JS by default uses a crappy string compare.
// (we use slice to clone the array so the
// original array won't be modified)
let results = [];
for (let i = 0; i < sorted_arr.length - 1; i++) {
if (sortFunc(sorted_arr[i + 1], sorted_arr[i]) === 0) {
results.push(sorted_arr[i]);
}
}
return results;
}
var values = [
{ name: 'Car',Data:'Required',value:'Vehicle' },
{ name: 'Auto',Data:'Required',value:'Vehicle'},
{ name: 'Bike',Data:'Required',value:'Vehicle'},
{ name: 'Car',Data:'Required',value:'Vehicle' }
];
var sortFunc = (a, b) => {
return (a.name !== b.name) ? a.name.localeCompare(b.name)
: (a.Data !== b.Data) ? a.Data.localeCompare(b.Data)
: a.value.localeCompare(b.value);
};
console.log(`The duplicates are ${JSON.stringify(findDuplicates(values))}`);
// prints The duplicates are [{"name":"Car","Data":"Required","value":"Vehicle"}]
Couple of differences from original answer:
1. The sortFunc is defined as per your data.
2. Since your input is array of objects, the sortFunc is reused for equality check.

Filter a JSON object with forEach

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!

Angular - Only push to array if unique

I have an Angular application that collects values of items for an invoice, I want to make sure only unique items are being added to this collection but am having no luck.
I am pushing 3 pieces of information to this collection: id, price, and type. I want to make sure there is nothing in the collection currently matching those 3 points.
// My container
$scope.invoice = {
items: [{
}]
}
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
if ($scope.invoice.items.indexOf(item.id) != $scope.item.id)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
// Trying to avoid collections like this
invoice: {
items:
[ { } , {
id: 25
price: 0
type: photo
} , {
id: 25
price: 0
type: photo
} ]
}
.filter is pretty much what you need.
$scope.addPhoto = function() {
console.log('Withdrawing Photo: '+ $scope.item.id);
var matches = $scope.invoice.items.filter(function(datum) {
return datum.id === $scope.item.id &&
datum.price === $scope.item.price &&
datum.type === $scope.item.type;
});
if (!matches.length)
{
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
}
}
Semi-contrived JSFiddle
This is the solution I came up with to solve my problem, hopefully it helps someone else.
$scope.addPhoto = function () {
console.log('Withdrawing Photo: ' + $scope.item.id);
var newItemId = $scope.item.id;
var newItemPrice = $scope.item.price;
var newItemType = 'photo';
var matches = true;
// Make sure user hasnt already added this item
angular.forEach($scope.invoice.items, function(item) {
if (newItemId === item.id && newItemPrice === item.price && newItemType === item.type) {
matches = false;
$scope.message = 'You have already selected to withdraw this item!';
}
});
// add item to collection
if (matches != false) {
$scope.invoice.items.push({
id: $scope.item.id,
price: $scope.item.price,
type: 'photo'
});
$scope.total += $scope.item.price;
$scope.message = 'Total Amount Selected';
}
};
YOu can simple pop opposite of push
array.splice(array.pop(item));

Categories