Object returning as undefined - javascript

If I call the find function APP.count() all is ok I am getting the correct result but when I call APP.add() I getting this.basket is undefined. I don't get why this is happening?
var APP = (function() {
var
basket = [
{ id: 100, price: 10, description: '', name: 'item one', quantity: 10, url: '' },
{ id: 200, price: 20, description: '', name: 'item two', quantity: 15, url: '' }
],
find = function(item) {
for(var i = 0; i < this.basket.length; i++) {
if(this.basket[i].id === item) {
return i
}
}
return null
},
add = function(item) {
var itemFound = find(item)
},
count = function() {
var total = 0;
for(var i = 0; i < this.basket.length; i++) {
total = total + this.basket[i].quantity
}
return total
};
return {
basket: basket,
find: find,
add: add,
count: count
};
})();
APP.count() /* works */
APP.add() /* returns this.basket as undefined */

The problem is from the call of find(item) in the add function.
Calling find function like that will not use the context of APP object as this, so this.basket will be undefined.
You can check what is the current context this with a simple console.log(this)
So if you want to call the find function with the context of APP, in the add function you need to call this.find(item)

Hi the issue is with the this reference when you call find method by add()
add = function(item) {
var itemFound = find(item)
},
this keyword is referring the window object
try with this below is the running code
var APP = (function() {
var
basket = [
{ id: 100, price: 10, description: '', name: 'item one', quantity: 10, url: '' },
{ id: 200, price: 20, description: '', name: 'item two', quantity: 15, url: '' }
],
find = function(item) {
for(var i = 0; i < this.basket.length; i++) {
if(this.basket[i].id === item) {
return i
}
}
return null
},
add = function(item) {
var itemFound = this.find(item) //changed
return itemFound; //changed
},
count = function() {
var total = 0;
for(var i = 0; i < this.basket.length; i++) {
total = total + this.basket[i].quantity
}
return total
};
return {
basket: basket,
find: find,
add: add,
count: count
};
})();

Related

How to find the first occurrence of the matched object and break all nested loop in JavaScript

I am trying to find the first occurrence of id from the nested data and if it is founds want to update which path it took to reach there with the index and move to the next iterations.
For Example:
let error = [
{
id: 1,
message: 'test1',
key: 'surname',
type:1,
path: [],
},
{
id: 1,
message: 'test12',
key: 'firstname',
type:2,
path: [],
},
{
id: 2,
message: 'test2',
key: 'surname',
type:2,
path: [],
},
];
//data
data = {
txn: [
{
actions: [
{
source: [
{
type: 1,
id: 1,
profile: {
firstname: 'data1',
},
},
],
cond: [
{
type: 2,
id: 1,
profile: {
firstname: 'data1',
surname: 'data2',
},
onb: [
{
type: 2,
id: 2,
profile: {
firstname: 'data21',
surname: 'data22',
},
},
],
},
],
},
],
},
],
};
When id=1 is found in the nested data and type 1 is matched at the source of the 0 indexes, I wanted to update the path with the ['txn',0,'actions',0,'source',0] and move to the next error object
when id:1 is found in the nested data and type 2 matched ['txn',0,'actions',0,'cond',0]
when id:2 is found in the nested data and type 2 matched ['txn',0,'actions',0,'cond',0,'onb',1]
so my output would be
error = [
{
id: 1,
message: 'test1',
key: 'surname',
type:1,
path: ['txn',0,'actions',0,'source',0],
},
{
id: 1,
message: 'test12',
key: 'firstname',
type:2,
path: ['txn',0,'actions',0,'cond',0],
},
{
id: 2,
message: 'test2',
key: 'surname',
type:2,
path: ['txn',0,'actions',0,'cond',0,'onb',1]
},
];
I tried the following code but two issues ,I am facing
it is not updating the path
it is not ending the loop properly.
Stackblitz:https://stackblitz.com/edit/js-nsebln?file=index.js
function findVal() {
error.forEach((ev) => {
let stop = false;
//console.log(ev)
//search for occurance of the id with type matching
//if matched update the value in the error
//move to the next error once first occurance found
for (let i = 0; i < data.txn.length; i++) {
let actiondata = data.txn[i].actions;
for (let j = 0; j < actiondata.length; j++) {
let sourcedata = actiondata[j].source;
for (let k = 0; k < sourcedata.length; k++) {
if (ev.id === sourcedata[k].id && sourcedata[k].type == ev.type) {
console.log('matched', i, j, k);
//matched
//update error object
ev.path.push('txn');
console.log(ev.path);
ev.path.push(i);
ev.path.push('actiondata');
ev.path.push(j);
ev.path.push('source');
ev.path.push(k);
stop = true;
}
if (stop) {
break;
}
}
//cond loop
let conddata = actiondata[j].cond;
for (let l = 0; l < conddata.length; l++) {
if (
ev.id === conddata[l].id &&
!stop &&
conddata[l].type == ev.type
) {
console.log('matched', i, j, l);
//matched
//update error object
ev.path.push('txn');
ev.path.push(i);
ev.path.push('actiondata');
ev.path.push(j);
ev.path.push('cond');
ev.path.push(l);
stop = true;
//onb loop
let onbdata = conddata[l].onb;
for (let m = 0; m < onbdata.length; m++) {
if (
ev.id === onbdata[m].id &&
!stop &&
onbdata[m].type === ev.type
) {
//matched
//update error object
ev.path.push('txn');
ev.path.push(i);
ev.path.push('actiondata');
ev.path.push(j);
ev.path.push('cond');
ev.path.push(l);
ev.path.push('onb');
ev.path.push(m);
stop = true;
}
if (stop) {
break;
}
}
}
if (stop) {
break;
}
}
if (stop) {
break;
}
}
if (stop) {
break;
}
}
console.log(ev);
});
}
findVal();
Can anyone please help me what I am doing wrong?

remove the second occurrence of array object with same name

I have this array (java script array of objects)
users=[{name:'arrow',age:50,id:444}
{name:'bow',age:66,id:884}
{name:'arrow',age:30,id:99},
{name:'apple',age:50,id:999}
{name:'bow',age:50,id:9669}]
I want to remove second occurrence of same name , in this case , I want to remove {name:'arrow',age:30,id:99} and {name:'bow',age:50,id:9669} and retain first occurrences{name:'arrow',age:50,id:444} and {name:'bow',age:66,id:884}
Resulting array should be :
users= [{name:'arrow',age:50,id:444}
{name:'bow',age:66,id:884},
{name:'apple',age:50,id:999}]
const users = [
{ name: 'arrow', age: 50, id: 444 },
{ name: 'bow', age: 66, id: 884 },
{ name: 'arrow', age: 30, id: 99 },
{ name: 'apple', age: 50, id: 999 },
{ name: 'bow', age: 50, id: 9669 }
]
const uniqueUsers = users.reduce((acc, user) => {
if (!acc.find(u => u.name === user.name)) {
acc.push(user)
}
return acc
}, [])
I'd go with the approach of array.filter:
function removeDuplicateKeyFromArray(arrayOfObjects,keyName){
keyHolder = {}
arrayOfObjects.filter((obj)=>{
if(keyHolder[obj.keyName]){
return false
}
keyHolder[obj.keyName] = 1 //or true
return true
})
}
I would create 2 for-loops, to filter out any duplicates.
here's my code:
let users = [{name:'arrow',age:50,id:444},
{name:'bow',age:66,id:884},
{name:'arrow',age:30,id:99},
{name:'apple',age: 50,id: 990},
{name:'bow',age: 50,id: 9669}]
for (let i = 0; i < users.length; i++) {
for(let x = 0; i < users.length; i++) {
if(users[i].name == users[x].name) {
users.splice(users[x], 1)
}
}
}

Trying to calculate the total score based on answer's value in react.js/javascript

question part
class PersonalityQuiz extends React.Component {
constructor() {
super();
this.mc = [];
this.mc.push([
{ value: 1, text: "raphael" },
{ value: 2, text: "donatello" },
{ value: 3, text: "leonardo" },
{ value: 4, text: "michaelangelo" }
]);
this.mc.push([
{ value: 1, text: "fluttershy" },
{ value: 2, text: "pinkie pie" },
{ value: 3, text: "rainbow dash" },
{ value: 4, text: "rarity" }
]);
this.state = {
score: 0
};
}
part for review based on answer total score should increase by the value of the answer (from 1 to 4). not much code afterwards
handleShowScore = e => {
let a = document.querySelectorAll("select");
let newScore = 0;
for (let i = 0; i < a.length; i++) {
var newScore = newScore + a[i].value;
}
this.setState({
score: newScore
});
};
You are creating another newScore variable in the loop because var and let both create a new variable. So the original never gets updated. Change var newScore = newScore + a[i].value; to newScore = newScore + a[i].value; or use shorthand increment newScore += a[i].value;

how can i push price into object using javascript?

Purchasedata.find(function(err, purchasedatas) {
if (err) {
return handleError(res, err);
}
var totalprice = 0;
for (var i = 0; i < purchasedatas.length; i++) {
findProduct(i, function(i, price) {
});
}
function findProduct(i, callback) {
Productpointallocation.find({
'productcode': purchasedatas[i].ItemCode
}).exec(function(err, productpointallocations) {
if (err) {
return handleError(res, err);
}
var pointMultiplier = 0;
if (!productpointallocations) {
pointMultiplier = 0;
} else if (productpointallocations.length == 0) {
pointMultiplier = 0;
}
if (pointMultiplier >= 0) {
var totalprice = (parseFloat(purchasedatas[i].ItemCost.value)) / 10 * pointMultiplier;
purchasedatas.push({price:totalprice,productname:productpointallocations[0].productname});
console.log(purchasedatas);
}
});
}
});
In purchasedata i am getting two objects
[ { _id: 592fbd65304a7315f87d3f40,
ItemCode: '10',
PurchaseQuantity: 3,
ItemCost: 15,
},
{ _id: 592fbd65304a7315f87d3f3f,
ItemCode: '6',
PurchaseQuantity: 1,
ItemCost: 5,
}]
based on ItemCode i am calculating price. after calculating price i want push price and product name into purchasedatas object
purchasedatas.push({price:totalprice,productname:productpointallocations[0].productname});
i wrote above code but i am getting object like this
[ { _id: 592fbd65304a7315f87d3f40,
ItemCode: '10',
PurchaseQuantity: 3,
ItemCost: 15,
},
{ _id: 592fbd65304a7315f87d3f3f,
ItemCode: '6',
PurchaseQuantity: 1,
ItemCost: 5,
},
{ price: 4.5, productname: ' ADAPTER-PCS' } ]
[ { _id: 592fbd65304a7315f87d3f40,
ItemCode: '10',
PurchaseQuantity: 3,
ItemCost: 15,
},
{ _id: 592fbd65304a7315f87d3f3f,
ItemCode: '6',
PurchaseQuantity: 1,
ItemCost: 5,
},
{ price: 4.5, productname: 'ADAPTER-PCS' },
{ price: 1, productname: 'UNIVERSAL AC DC ' } ]
my expectation result after pushing price and productname
[ { _id: 592fbd65304a7315f87d3f40,
ItemCode: '10',
PurchaseQuantity: 3,
ItemCost: 15,
price: 4.5,
productname: 'ADAPTER-PCS'
},
{ _id: 592fbd65304a7315f87d3f3f,
ItemCode: '6',
PurchaseQuantity: 1,
ItemCost: 5,
price: 1,
'productname: 'UNIVERSAL AC DC '
}]
Javascript's Array.push() function will append an object to an array. If you want to add attributes to elements that are in the array already, you'll have to modify the objects. To do that you'll need to find the index of the object in the array, for example by looping over it and comparing the id.
If you want to modify all the Objects inside of the array you can also use Array.map()
You don't say push since the "push" method is only for arrays, but in fact you can add it to the object, for example:
var obj = {a: 1, b:2}
obj["c"] = 3
and it will be like that:
obj = {a: 1, b: 2, c: 3}
It's not about pushing, but about "joining" 2 objects into 1 array element - not tested but "Object.assign" should do the trick.
Purchasedata.find(function(err, purchasedatas) {
if (err) {
return handleError(res, err);
}
var totalprice = 0;
for (var i = 0; i < purchasedatas.length; i++) {
findProduct(i, function(i, price) {
});
}
function findProduct(i, callback) {
Productpointallocation.find({
'productcode': purchasedatas[i].ItemCode
}).exec(function(err, productpointallocations) {
if (err) {
return handleError(res, err);
}
var pointMultiplier = 0;
if (!productpointallocations) {
pointMultiplier = 0;
} else if (productpointallocations.length == 0) {
pointMultiplier = 0;
}
if (pointMultiplier >= 0) {
var totalprice = (parseFloat(purchasedatas[i].ItemCost.value)) / 10 * pointMultiplier;
purchasedatas[i] = Object.assign({},purchasedatas[i], {price:totalprice,productname:productpointallocations[0].productname});
console.log(purchasedatas);
}
});
}
});
EDIT: it seems that there's some mongo object instead of simple key-value pairs. Try something like that:
if (pointMultiplier >= 0) {
var totalprice = (parseFloat(purchasedatas[i].ItemCost.value)) / 10 * pointMultiplier;
purchasedatas[i] = Object.assign({},JSON.parse(JSON.stringify(purchasedatas[i])), {price:totalprice,productname:productpointallocations[0].productname});
console.log(purchasedatas);
}
or
if (pointMultiplier >= 0) {
var totalprice = (parseFloat(purchasedatas[i].ItemCost.value)) / 10 * pointMultiplier;
purchasedatas[i] = Object.assign({},tojson(purchasedatas[i]), {price:totalprice,productname:productpointallocations[0].productname});
console.log(purchasedatas);
}
So here is it how I believe it would happen,
First iterate over the array (purchasedatas) then over each object inside it:
for (var i = 0; i < purchasedatas.length; i++) {
for (var key in obj) {
if(purchasedatas[i]["ItemCode"] === req.body.ItemCode) {
purchasedatas[i]["price"] = req.body.price;
purchasedatas[i]["productname"] = req.body.productname;
}
}
}
return purchasedatas;
Hope that this is what you want or at least what you are asking for.

combine array of objects by key

I am trying to combine/merge 2 array of objects by key in my case id.
Objective:
I am expecting a results where I would have array containing all objects with ids 1,2,3,4 as per example
Order of merging should not affect number of objects in result for example combine(arr1,arr2) or combine(arr2,arr1) should have array with same number of objects
Order of merging can only affect resulting object for example in case of combine(arr1,arr2) arr2 key,values pair can override arr1 key,values just like deep jquery extend $.extend( true, arr1ObJ,arr2ObJ );
JSFIDDLE: https://jsfiddle.net/bababalcksheep/u2c05nyj/
Sample Data:
var arr1 = [{
id: 1,
name: "fred",
title: "boss"
}, {
id: 2,
name: "jim",
title: "nobody"
}, {
id: 3,
name: "bob",
title: "dancer"
}];
var arr2 = [{
id: 1,
wage: "300",
rate: "day"
}, {
id: 2,
wage: "10",
rate: "hour"
}, {
id: 4,
wage: "500",
rate: "week"
}];
var Result = [{
"id": 1,
"name": "fred",
"title": "boss",
"wage": "300",
"rate": "day"
}, {
"id": 2,
"name": "jim",
"title": "nobody",
"wage": "10",
"rate": "hour"
}, {
id: 3,
name: "bob",
title: "dancer"
}, {
id: 4,
wage: "500",
rate: "week"
}];
Here's a solution. It basically goes through each element of arr2 and checks to see if there's an element with a matching ID arr1. If so, it updates the matching element in arr1 with arr2's values. If there is no match, it simply pushes the element in arr2 onto arr1.
var arr1 = [{id: 1,name: 'fred',title: 'boss'},
{id: 2,name: 'jim',title: 'nobody'},
{id: 3,name: 'bob',title: 'dancer'}];
var arr2 = [{id: 1,wage: '300',rate: 'day'},
{id: 2,wage: '10',rate:'hour'},
{id: 4,wage: '500',rate: 'week'}];
function combineArrays(arr1, arr2) {
for(var i = 0; i < arr2.length; i++) {
// check if current object exists in arr1
var idIndex = hasID(arr2[i]['id'], arr1);
if(idIndex >= 0){
//update
for(var key in arr2[i]){
arr1[idIndex][key] = arr2[i][key];
}
} else {
//insert
arr1.push(arr2[i]);
}
}
return arr1;
}
//Returns position in array that ID exists
function hasID(id, arr) {
for(var i = 0; i < arr.length; i ++) {
if(arr[i]['id'] === id)
{
return i;
}
}
return -1;
}
var combine = combineArrays(arr1, arr2);
output(combine);
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
var arr1 = [{
id: 1,
name: 'fred',
title: 'boss'
}, {
id: 2,
name: 'jim',
title: 'nobody'
}, {
id: 3,
name: 'bob',
title: 'dancer'
}];
var arr2 = [{
id: 1,
wage: '300',
rate: 'day'
}, {
id: 2,
wage: '10',
rate: 'hour'
}, {
id: 4,
wage: '500',
rate: 'week'
}];
function combineArrays(arr1, arr2) {
for (var i = 0; i < arr2.length; i++) {
var idIndex = hasID(arr2[i]['id'], arr1);
if (idIndex >= 0) {
for (var key in arr2[i]) {
arr1[idIndex][key] = arr2[i][key];
}
} else {
arr1.push(arr2[i]);
}
}
return arr1;
}
function hasID(id, arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i]['id'] === id) {
return i;
}
}
return -1;
}
var combine = combineArrays(arr1, arr2);
output(combine);
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
How about something along the lines of this:
function combineArrays(arr1, arr2, keyFunc) {
var combined = [],
keys1 = arr1.map(keyFunc),
keys2 = arr2.map(keyFunc),
pos1 = keys1.map(function (id) {
return keys2.indexOf(id);
}),
pos2 = keys2.map(function (id) {
return keys1.indexOf(id);
});
arr1.forEach(function (item, i) {
combined.push( $.extend(item, arr2[pos1[i]]) );
});
arr2.forEach(function (item, i) {
if (pos2[i] === -1) combined.push( item );
});
return combined;
}
used as
var combine = combineArrays(arr1, arr2, function (item) {
return item.id;
});
var arr1 = [
{ id: 1, name: 'fred', title: 'boss' },
{ id: 2, name: 'jim', title: 'nobody' },
{ id: 3, name: 'bob', title: 'dancer' }
];
var arr2 = [
{ id: 1, wage: '300', rate: 'day' },
{ id: 2, wage: '10', rate: 'hour' },
{ id: 4, wage: '500', rate: 'week' }
];
function combineArrays(arr1, arr2, keyFunc) {
var combined = [],
keys1 = arr1.map(keyFunc),
keys2 = arr2.map(keyFunc),
pos1 = keys1.map(function (id) {
return keys2.indexOf(id);
}),
pos2 = keys2.map(function (id) {
return keys1.indexOf(id);
});
arr1.forEach(function (item, i) {
combined.push( $.extend(item, arr2[pos1[i]]) );
});
arr2.forEach(function (item, i) {
if (pos2[i] === -1) combined.push( item );
});
return combined;
}
var combine = combineArrays(arr1, arr2, function (item) {
return item.id;
});
output(combine);
//
//
//
/* pretty Print */
function output(inp) {
var str = JSON.stringify(inp, undefined, 4);
$('body').append($('<pre/>').html(str));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Categories

Resources