Setting attribute value of object inside array using _.find - javascript

I am pretty sure there is a better way of doing this. In the code below, I am trying to set the value of item object inside selected_items array. I've discovered that using '=' instead of '==' returned an altered version of the found object (a behavior that I found useful in other parts of my code).
Is this a good idea? I would really like to know a cleaner way of doing this using lodash.
$scope.increase_item_quantity = function(item_pk, addition){
if($scope.is_item_selected()){
var item_quantity = $scope.get_item_quantity();
if(!(item_quantity < 1 && addition == -1)){
console.log('adding...')
$scope.selected_items = _.result(_.find($scope.selected_items, function(item) {
return item.quantity = addition;
}), 'quantity');
}
}
}
Via the method above, I am trying to set the quantity of the item with a particular id.

Simple vanilla js
$scope.selected_items.forEach(function(item){
item.quantity = new_quantity;
});

Related

How to Check the variable value is [""] in JavaScript

Example:
When I check a variable containing this value [""] it returns false.
var th=[]
th.push("");
if($("#multiselect").val()==th)
It returns always false.
Thank you.
Edit 1:
changed Var to var. It was a typo.
Edit 2:
Actually, the problem I faced was I was trying to get the value from a multi-select input. The multi-select input sometimes returns values as [""] even I haven't selected any values basically it's a plugin. So I was confused and I thought [""] is a fixed primitive value like 1, 10, "bla blah",.. So I tried to compare it with the same array as the right-hand side of the '=' operator.
It was stupid. Now I posted the solution to my problem and I explained my stupidity.
there are two things:
Change Var to var
You can use includes method of Array as:
var th = [] <==== chnage Var to var
th.push("");
if(th.includes($("#multiselect").val())) { <=== you can use includes method of array
// DO whatever you want
}
Make sure var is lowercased.
You are accessing th as an array, so you’ll need to specify the index of the value you are checking: th[0]
Use triple equals, too: .val()===th[0]
Double check the jquery docs if you’re still running into trouble.
Happy coding!
A couple of things to consider:
You have a typo in the code above; var is valid; Var is invalid.
Browser will aptly complain to solve this typo.
You are comparing an array to DOM value; this will always be false.
DOM is a costly process. Unless the value associated is dynamic, its better to read once, store value into a variable and continue processing instead of reading from DOM always.
You could choose to try something on these lines:
let arr = [1,2,3,4];
let domValue = $("#multiselect").val();
arr.push(5);
arr.map((el, ix) => {
if el === domValue return true; //or choose to do something else here.
});
var th=[]; //It is var not Var
th.push("");
if($("#multiselect").val()==th[0]) // change th to th[0]
I am unable to comment so having to use an answer for now. Are you trying to check if an array has any values? If so you can use
if(th.length){
// do something
}
If you want to check a normal variable for empty string you can simply use
if(th == “”){
//do something
}
I found the solution after a couple of days when I posted this question. Now I can feel how stupid this question was.
Anyway, I'm answering this question so it might help others.
Answer to my question:
When two non-primitive datatype objects(which is the Array here) are compared using an assignment operator, it compares its reference of the object. So the object creation of both arrays would be different. If I want to check the array has [""] value, I should do something like the below.
function isArrValEmptyCheck(value) {
return !value || !(value instanceof Array) || value.length == 0 || value.length == 1 && value[0] == '';
}
console.log(isArrValEmptyCheck([""]));//returns true
console.log(isArrValEmptyCheck(["value1"]));//returns false
Sorry for the late response. Thanks to everyone who tried to help me.

Check a variable with multiple values in jquery

I need to check if a variable in if condition as follows.
if(table_block_id == ('customer_details' || 'billing_details' || 'shipping_details')){
}
I know it's the wrong method . Is there any other way to check all values in a single line ?
The easiest way would be to use Array.prototype.includes as EKW suggested in his answer.
However, due to its poor support I would recommend using Array.prototype.indexOf instead:
if(["customer_details", "billing_details", "shipping_details"].indexOf(table_block_id) !== -1){
// code
}
There are a few methods you could use. I quite like the following:
if(["customer_details", "billing_details", "shipping_details"].includes(table_block_id)){
// code
}
You can put the options in array and use jQuery $.inArray() or javascript indexOf() to search array.
var a = 'customer_details';
arr = ['customer_details', 'billing_details', 'shipping_details'];
if($.inArray(a, arr) != -1) // With jQuery
//code
else
//code

_.findWhere from underscorejs to JQuery

I am trying to implement this code: http://jsfiddle.net/wQysh/351/ in my project.
Everything is fine except for the line:
t = _.findWhere(sc, { id : Number(a.trim()) });
They have used underscorejs and I want to translate this to JQuery without using another lib.
I went through the doc and it stated:
findWhere_.findWhere(list, properties)
Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
If no match is found, or if list is empty, undefined will be returned.
But still I am confused about this since I am not sure what to return exactly (as first value). Can anyone give me a JQuery alternative to that line?
Thanks in advance..
If you don't the generic nature of _.findWhere() you can use a simple while loop, and compare the id to the numeric value of a (fiddle):
t = 0; // t is used as a counter
aValue = Number(a.trim()); // assign the value to a variable instead of iterating it
while (t < sc.length && sc[t].id !== aValue) { t++; }; // find the index where the id is the as the aValue
t < sc.length && toSet.push(sc[t]); // if t is less the sc.length we found the item in the array
If you need a findWhere without underscore try this gist.
I also used this example in my project. And also needed use JQuery instead of Underscore.
Here is my solution:
t = sc.filter(function (el) { return el.id === a });
It work perfect for me;
If you use number for ids, you can also convert a to integer
t = sc.filter(function (el) { return el.id === parseInt(a, 10) });

Remove element by value a-la Knockout

This is something of a two-part question that has to do with manipulating elements within an array of data in Angular. It seems like pretty universally the way to remove an element from an array in the ViewModel is
$scope.array.splice(index, 1);
This seems a little shaky to me, and I prefer how Knockout handles this with .remove and observable arrays: vm.array.remove(item).
I have found that you can do this which is a bit better:
$scope.array.splice($scope.array.indexOf(item), 1);
but it's more verbose and .indexOf may not work as you expect depending upon what item is.
Is there any construct for Angular that will allow you to easily remove an item from an array by its value?
Also based on this video from Egghead.io, it makes sense to remove dependencies within ViewModel methods and not rely on scope. Would it be preferred to pass in the array that you were removing the item from as well:
<input type=submit ng-click="remove(array, item)">
array.splice(array.indexOf(item), 1)
Or is there a reason to prefer using $scope (or the controller) within the remove method?
Unfortunately or Fortunately, Knockout does it the same way we are doing with Angular i.e. splice method
If you look at the source code of observableArray.remove(item) in knockout library -
'remove': function (valueOrPredicate) {
var underlyingArray = this.peek();
var removedValues = [];
var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate) ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
for (var i = 0; i < underlyingArray.length; i++) {
var value = underlyingArray[i];
if (predicate(value)) {
if (removedValues.length === 0) {
this.valueWillMutate();
}
removedValues.push(value);
underlyingArray.splice(i, 1);
i--;
}
}
if (removedValues.length) {
this.valueHasMutated();
}
return removedValues;
}
It does the same thing, it parse through the array and compare the given value and performs splice.
They have written reusable module for the same to make it easy to use for developers. I believe you can do the same by writing custom directive in your Angular code. You can use above code for a reference. It's just that Angular does not have any reusable directive for that... yet.. may be we can ask for a pull request after making one :-)
But your question is very good and one should have such reusable module.

Syntax explanation please

I'm trying to understand 2 different lines of code below. My javascript is weak, trying to improve it with jquery (hmmmm)
What I'm trying to use the drag sort plugin from http://dragsort.codeplex.com/ specifically I'm using the http://dragsort.codeplex.com/SourceControl/changeset/view/74794#1025059 example.
I've gotten to the stage now where I've used this approach
var serialStr = "";
$("#list1 li").each(function(i, elm) {
serialStr = (i > 0 ? "|" : "") + $(elm).children().html();
});
The example has the following.
var serialStr = new Array();
$("#list1 li").each(function(i, elm) {
serialStr[] = = $(elm).attr("itemId");
});
The reason I have the first approach is that I was testing everything out and its what they had in the HTML example. I'm now trying to save the state so I've moved onto the php example.
So my question is what is the primary difference going on in the different lines here? My understanding of the first line is that its selecting each child element inside of the li tag on list1 I don't really get the (i > 0 ? "|" : "") bit.
In the second snipplet from what I understand its selecting every attribute with the itemID assignee in list1 li ?
serialStr[] = (i > 0 ? "|" : "") +$(elm).children().html() is a shorthand if-clausule. It does the same as:
if(i > 0) {
serialStr[] = "|" +$(elm).children().html();
} else {
serialStr[] = "" +$(elm).children().html();
}
The expression (i > 0 ? "|" : "") is using the conditional operator condition ? expr1 : expr2 to not to prefix the first value with | but only every following values.
But the expression serialStr[] = = $(elm).attr("itemId") is invalid syntax. Javascript does not have a push operator [] like PHP has. Use Array.prototype.push instead.
I don't think you've pasted the code exactly as neither snippet makes sense. The first seems to want to be concatenating strings together, but is missing the += that would make that happen; the second is making a list, presumably to join() together afterwards, but is using some odd []= syntax that does not exist in JavaScript.
I don't really get the (i > 0 ? "|" : "") bit.
First time round the loop, pick "", subsequent times pick "|". This is the traditional way to make a string where each element is separated by a character.
But join() is generally a cleaner way to do that, and you can use map() to run a function over an array returning a new array, instead of having to manually create one:
var itemIds= $('#list1 li').map(function() {
return $(this).attr('itemId');
}).get().join('|');
(Or $(this).html() if you really want to get the HTML content, which sounds a bit questionable.)
map() is a jQuery function but ECMAScript Fifth Edition has a map() method on plain arrays too. About map in general.

Categories

Resources