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
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,
)
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.
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.
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!
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));