Remove from Cart is not Working in AngularJS - javascript

Here is my code
$scope.cart = [];
$scope.addToCart = function (cat) {
var found = false;
$scope.cart.forEach(function (item) {
if (item.id === cat.product_id) {
item.quantity++;
found = true;
}
});
if (!found) {
$scope.cart.push(angular.extend({quantity: 1}, cat));
}
};
//remove from cart function
$scope.removeToCart = function (cat) {
console.log(cat.product_id);
var found = false;
$scope.cart.forEach(function (item) {
if (item.id === cat.product_id) {
item.quantity--;
found = true;
}
});
if (!found) {
$scope.cart.push(angular.extend({quantity: 1}, cat));
}
};
console.log($scope.cart);
$scope.getCartPrice = function () {
var total = 0;
$scope.cart.forEach(function (cat) {
total += cat.finalprice * cat.quantity;
});
return total;
};

Probably you need to remove this bit from your removeToCart function:
if (!found) {
$scope.cart.push(angular.extend({quantity: 1}, cat));
}
If "cat" is not found in the cart, you'll always add one with quantity of 1. Both "addToCart" and "removeToCart" seems identical for me, apart the item.quantity++ and item.quantity-- lines.

Related

How to call method recursively in typescript

I want to call the filterArr inside the filterArr. Here is my implementation.
filterArr(array, search) {
var result = [];
array.forEach((a)=> {
var temp = [],
o = {},
found = false;
if (a.name === search) {
this.o.name = a.name;
found = true;
}
if (Array.isArray(a.children)) {
temp = this.filterArr(a.children, search);//***Cannot read property 'filterArr' of undefined***
if (temp.length) {
this.o.children = temp;
found = true;
}
}
if (found) {
result.push(o);
}
});
return result;
}
How to call the filterArr method without any error?
You have to use Arrow function to get hold on correct this, so you need to change array.forEach(function (a) { to use `Arrow function
array.forEach((a) => {

How to avoid reading previous JSON array value which are stored in page before page refresh

I want to avoid reading the previous objects pushed in the JSON array. As shown in the image.
I'm Self learning these concepts. so i need help, about is this the right method to add and read values.
Also i dont know how to ask this question technically. so i would appreciate if someone would tell me how this question should be asked. So that i can atleast improve it for better understanding.
JQUERY
$("#click").click(function(event)
{
event.preventDefault();
var $form = $('#myform');
var $boxes =$("input[id=myCheckboxes]:checked").length;
if($boxes==0)
{
alert("Choose atleast one Category");
}
else if($form.valid() && $boxes>0)
{
//if form is valid action is performed
var data = $( "#myform" ).serializeArray();//serialize the data
var valuesArray = $('input:checkbox:checked').map( function() {
return this.value;
}).get().join(",");
data.push({ name: 'panel', value: valuesArray});
//convert json array into object
var loginFormObject = {};
$.each(data,
function(i, v) {
loginFormObject[v.name] = v.value;
});
array.push(loginFormObject);
alert("Added Successfully");
viewFunction(array);
return false;
}
})
//view function
function viewFunction(array)
{
console.log(array);
var panel_arr = ["", "Regular", "Reduced Fee", "Limited Assurance","Court Programs"];
var ul_block = $("<ul/>");
$.each(array, function(i, data)
{
var panels = data.panel.split(",");
var uli_block = $("<ul/>");
$.each(panels, function(j, jdata)
{
var ulii_block = $("<ul/>");
$edit = $('<a/>').attr('href', 'javascript:;').addClass('btn btn-default active').attr('role', 'button').text('Edit')
.css('margin-left', 5);
$del = $('<a/>').addClass('btn btn-default active').attr('role', 'button').text('Delete')
.css('margin-left', 5);
$(ulii_block).append($("<li/>").html(data.ptitle).append($edit,$del));
$(uli_block).append($("<li/>").html('<span class="Collapsable">'+panel_arr[panels[j]]+'</span>')).append(ulii_block);
$edit.click(editFunction.bind(null, data));//bind data to function
});
$(ul_block).append($("<li/>").html('<span class="Collapsable">'+data.gpanel+'</span>').append(uli_block));
});
$("#addMember").append(ul_block);
$(".Collapsable").click(function () {
$(this).parent().children().toggle();
$(this).toggle();
});
$(".Collapsable").each(function(){
$(this).parent().children().toggle();
$(this).toggle();
});
}
i made this method to compare between 2 of my json objects:
//tempObj is old object and newObj is well your new JSON, this function returns bool
function isDifferentObj(tempObj, newObj) {
var tempObjLength = Object.keys(tempObj).length;
var newObjLength = Object.keys(newObj).length;
if (newObjLength >= tempObjLength) {
for (var key in newObj) {
if (typeof tempObj[key] != "undefined") {
if (newObj[key] != tempObj[key]) {
return true;
}
} else {
return true;
}
}
return false;
} else {
for (var key in tempObj) {
if (typeof newObj[key] != "undefined") {
if (tempObj[key] != newObj[key]) {
return true;
}
} else {
return true;
}
}
return false;
}
}
After a lot of trouble i found my problem. I was appending the result every time.
The code line which was making the trouble was this.
$("#addMember").append(ul_block);
I changed it to
$("#addMember").html(ul_block);
hence avoiding duplicates.

localStorage loadVote when refresh page

I have a vote up +1 one time by user, now I'm watching. I need loadVote when refresh page, because saveVote is running ok, I think of my solution is in return votes; of the loadVote function. And Where is ok the saveVote();, in the function once or after of return votes;
var voteUp = document.getElementById('vote-up');
var handUp = once(function() {
var total = Number(voteUp.innerHTML);
total += 1;
voteUp.innerHTML = total;
});
voteUp.addEventListener('click', handUp);
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context);
fn = null;
saveVote();
}
return result;
};
}
function saveVote() {
var votes = voteUp;
var data = Array.prototype.map.call(votes, function(vote){
return[vote];
});
localStorage.setItem('data', JSON.stringify(data));
console.log('saveVote');
}
function loadVote() {
var votes = JSON.parse(localStorage.getItem('data'));
if(!votes){
return;
}
Array.prototype.map.call(votes, function(vote){
return votes;
});
console.log(JSON.parse(localStorage.getItem('votes')));
}
loadVote();
love David Walsh's post on this HERE
DEMO
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
var voteUp = document.getElementById('vote-up');
var handUp = once(function() {
var total = Number(voteUp.innerHTML);
total += 1;
voteUp.innerHTML = total;
});
voteUp.addEventListener('click', handUp);
Simply do this:
voteUp.addEventListener('click', function(){
//call your function method to what you want to do with voteUp
//and call this
this.removeEventListener('click');
});

Filter multiple columns at the same time

Im using angularJS to create a list of items. Now I want to filter so that I can search in multiple columns at the same time. For example if I search for "Bob" all the columns containing "Bob" will show, and then I continue to search for "Bob 073" all columns containing the name "Bob" and the telephone-number that contains "073" will show.
I have created a filter that achieves something similar, but is hardcoded to specific columns and only works if I search for both columns.
app.filter('appFilter', function () {
return function (data, search) {
if (!search) {
return data;
} else {
var term = search;
var termsArray = term.split(' ');
return data.filter(function(item){
return item.name.indexOf(termsArray[0]) > -1 && item.phone.indexOf(termsArray[1]) > -1;
});
}
}
});
<input type="search" ng-model="search">
<div ng-repeat="item in items | appFilter:search )">
{{item.name}}, {{item.phone}}
</div>
I hope you understand what I mean.
Thanks.
myApp.filter('filterMultiple', ['$filter', function ($filter) {
return function (items, keyObj) {
var filterObj = {
data: items,
filteredData: [],
applyFilter: function (obj, key) {
var fData = [];
if (this.filteredData.length == 0)
this.filteredData = this.data;
if (obj) {
var fObj = {};
if (!angular.isArray(obj)) {
fObj[key] = obj;
fData = fData.concat($filter('filter')(this.filteredData, fObj));
} else if (angular.isArray(obj)) {
if (obj.length > 0) {
for (var i = 0; i < obj.length; i++) {
if (angular.isDefined(obj[i])) {
fObj[key] = obj[i];
fData = fData.concat($filter('filter')(this.filteredData, fObj));
}
}
}
}
if (fData.length > 0) {
this.filteredData = fData;
}
}
}
};
if (keyObj) {
angular.forEach(keyObj, function (obj, key) {
filterObj.applyFilter(obj, key);
});
}
return filterObj.filteredData;
}
}]);
Usage:
arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}

Find an element in an array recursively

I have an array of objects. Every object in the array has an id and an item property that is an array containing other object. I need to be able to find an element in an array by id. Here is a sample of what I have done so far, but the recursive function is always returning undefined.
How can I quit the function and return the item when I have called the function recursively several times?
$(function () {
var treeDataSource = [{
id: 1,
Name: "Test1",
items: [{
id: 2,
Name: "Test2",
items: [{
id: 3,
Name: "Test3"
}]
}]
}];
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems && subMenuItems.length > 0) {
for (var i = 0; i < subMenuItems.length; i++) {
var item;
if (subMenuItems[i].Id == id) {
item = subMenuItems[i];
return item;
};
getSubMenuItem(subMenuItems[i].items, id);
};
};
};
var searchedItem = getSubMenuItem(treeDataSource, 3);
alert(searchedItem.id);
});
jsFiddle
You should replace
getSubMenuItem(subMenuItems[i].items, id);
with
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
in order to return the element when it is found.
And be careful with the name of the properties, javascript is case sensitive, so you must also replace
if (subMenuItems[i].Id == id) {
with
if (subMenuItems[i].id == id) {
Demonstration
Final (cleaned) code :
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems) {
for (var i = 0; i < subMenuItems.length; i++) {
if (subMenuItems[i].id == id) {
return subMenuItems[i];
}
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
}
}
};
I know its late but here is a more generic approach
Array.prototype.findRecursive = function(predicate, childrenPropertyName){
if(!childrenPropertyName){
throw "findRecursive requires parameter `childrenPropertyName`";
}
let array = [];
array = this;
let initialFind = array.find(predicate);
let elementsWithChildren = array.filter(x=>x[childrenPropertyName]);
if(initialFind){
return initialFind;
}else if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childrenPropertyName]);
});
return childElements.findRecursive(predicate, childrenPropertyName);
}else{
return undefined;
}
}
to use it:
var array = [<lets say an array of students who has their own students>];
var joe = array.findRecursive(x=>x.Name=="Joe", "students");
and if you want filter instead of find
Array.prototype.filterRecursive = function(predicate, childProperty){
let filterResults = [];
let filterAndPushResults = (arrayToFilter)=>{
let elementsWithChildren = arrayToFilter.filter(x=>x[childProperty]);
let filtered = arrayToFilter.filter(predicate);
filterResults.push(...filtered);
if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childProperty]);
});
filterAndPushResults(childElements);
}
};
filterAndPushResults(this);
return filterResults;
}

Categories