0

I have a ng-click event on an <i> tag that looks like this:

ng-click="parent.Status != 'Open' || (item.Status='Retrospect')"

So if parent.Status is not equals to Open then item Status is set to Retrospect, this is ok.

But I want another check, I want to see if this item is editable, for this I have a bool variable, edit. Naturally I wrote it like this:

ng-click="parent.Status != 'Open' && edit || (item.Status='Retrospect')"

So, I thought that if parent.Status is not equals to Open AND edit equals true my item.Status will be updated, problem is that it was updated no matter if edit was true or false (thinking it's because the first check is true, so it doesn't care about edit)

i also tried it like this, but same problem:

ng-click="(parent.Status != 'Open' && edit) || (item.Status='Retrospect')"

.. using ( )

What am I missing? Should this not be possible?

EDIT: Seems like when doing like this:

ng-click="parent.Status != 'Open' || (item.Status='Retrospect')"

item.Status will be set to 'Retrospect' if parent.Status != 'Open' resovles to false, but the problem still persist.

Also, there may be some confuison here I think, I am not checking if parent.Status != 'Open' OR item.Status='Retrospect' I am running the command item.Status='Retrospect' IF parent.Status != 'Open' equals false

My bad Okay, I am so confused right now, but my code did in fact work, the problem was my understanding of ng-click true/false evaluation and also I used != instead of !== which may have caused some issues.

I will upvote most of the answers (cause all of you were right, just not me) and accept what helped me to understand the most. Thanks all!

sch
  • 1,368
  • 3
  • 19
  • 35
  • 1
    does your existing code (`ng-click="parent.Status != 'Open' || (item.Status='Retrospect')"` works correctly? According to [short circuit evaluation of logical operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators), your `item.Status` assignment is not evaluated if the first condition evaluates to true – iulian Apr 14 '16 at 09:01
  • @iulian you are correct, my code worked in 'reverse' (if it was 'Open') but the problem is the same – sch Apr 14 '16 at 09:32
  • 1
    check your `(parent.Status != 'Open' && edit)` condition. Again, if it evaluates to true, your assignment shall not pass. Currently, if either your `parent.Status != 'Open'` OR your `edit` is false, your item.status will get assigned. If you want to assign it if status is open and it is editable, try `!(parent.Status === 'Open' && edit)` – iulian Apr 14 '16 at 09:44

5 Answers5

3

Such statements are called as short circuit statements. but as per the rule for "||"

statement1 || statement2

in above, statement1 is always executed and evaluated, but statement2 is executed only if statement1 evaluates to false.

on contrary, the rule for "&&" is

statement1 && statement2

in above, statement1 is always executed and evaluated, but statement2 is executed only if statement1 evaluates to true.

check the below in console -

var parent = {};
parent.Status = "Close";
var edit = false;
var item = {};
item.Status = ""

parent.Status != 'Open' && edit || (item.Status='Retrospect');

item.Status;

the Status will be updated only when (parent.Status != 'Open' && edit) evaluates to false.

You can refer - http://sampsonblog.com/tag/short-circuit-evaluation

Hope this helps.

Khyati
  • 233
  • 1
  • 5
1

(item.Status='Retrospect') should be (item.Status === 'Retrospect') ...
Otherwise you are testing the return value of an assignment, which is always true... :-). As a side note, always use type-converting equality comparison (=== for == !== for != JavaScript)... (for a quite complete and clear explanation, see here).

Update: From your comment I see you really meant what you wrote... :-)
However, in that case, I'd do:

if (!(parent.Status !== 'Open' && edit)) item.Status = 'Retrospect'

or:

item.Status = (parent.Status !== 'Open' && edit) ? item.Status : 'Retrospect'
Community
  • 1
  • 1
MarcoS
  • 17,323
  • 24
  • 96
  • 174
  • No, I think you don't understand (or I don't...) but the first example works. this part `|| (item.Status='Retrospect')` 'runs' if the first part equals true, so it sets 'Status' to the string 'Retrospect' it doesn't check if it is that – sch Apr 14 '16 at 08:55
  • Sorry... Updated my answer. – MarcoS Apr 14 '16 at 09:03
  • yeah, but shouldn't my code work then? In `ng-click`? `ng-click="(parent.Status != 'Open' && edit) || (item.Status='Retrospect')"` – sch Apr 14 '16 at 09:11
  • updated my question, my code did work :) I was just very confused! Your examples helped me figure out my own mistakes, so I accept this. Thank you – sch Apr 14 '16 at 09:51
1

In your || construct, item.Status will update if the first condition (parent.Status != 'Open' && edit) is false, not if it is true. Your first code should work the same way.
It may be cleaner and less confusing to write:

if (parent.Status != 'Open' && edit) {item.Status = 'Retrospect';}

KWeiss
  • 2,954
  • 3
  • 21
  • 37
1

I think you better expand the code in a function.

In Html:

ng-click="doThing()"

In the javascript:

doThing() {
    if((parent.Status != 'Open') && edit) {
        item.Status = 'Retrospect';
    }
}
Dinsdale
  • 184
  • 3
  • 12
  • this is probably a good idea, but I'd like to know either way how to do it in `ng-click` – sch Apr 14 '16 at 09:10
  • 1
    well i would say this is the way you need to work with because writing such complex logic inside the directive would not look good.if you still wan to do it inside directive itself, then place the entire code within flower braces , `ng-click ="{ }"` – dreamweiver Apr 14 '16 at 09:45
0

Simply use ternary operator like this:

ng-click="parent.Status != 'Open' && edit = true? item.Status='Retrospect' : item.Status='Somethingelse or null'"
Naitik Adani
  • 226
  • 2
  • 10