-Event- Can Only Appear on the Left Hand Side of += or -=

Why expression as left-hand side in assignment doesn't always work?

The relevant bit of the specification is here:

It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is not simple.

and here.

The simplified version is that (if we leave destructuring aside) you can assign a value to a variable or to a property of an object.

Given (foo), the parenthesis are pointless and the expression is just a variable name. This is fine.

Given (foo1 && foo2 && foo3) the values are read from the variables, compared using the && operator and the outcome is a value.

You can't assign a value to a value, only to a property or a variable.

I keep getting this error The left-hand side of an assignment must be a variable, property or indexer

In C#, = means assignment to a variable or property. == means comparison.

This:

       bool y = x % 3 = 0;
bool z = x % 5 = 0;

means "assign 0 to x % 3 (and to y, though that is considered poor style in C#)", but x % 3 is not something you can assign to. You meant

       bool y = x % 3 == 0;
bool z = x % 5 == 0;

Now, while we're at it, let's get you into good habits while you're a new C# programmer so that you don't have to be broken of them later.

Plainly you are making an attempt at fizzbuzz-style questions, which means that you are probably practicing for an interview. Interviewers will look for small details.

  bool y = x % 3 == 0;
bool z = x % 5 == 0;

Why x, y and z? What do those mean? Nothing. You had a choice of any text in the universe and you chose to pick text that was meaningless. Interviewers notice that.

  bool divisbleByThree = current % 3 == 0;
bool divisibleByFive = current % 5 == 0;

Moving on:

if (y == true || z == true) {

Nothing says "I'm a novice programmer" louder than making a Boolean that compares a Boolean to a Boolean. y and z are already either true or false; comparing them to true is an identity operation. It's completely unnecessary because the answer to "is it true that it is true?" is the same as the answer to "is it true?" Just write

if (divisibleByThree || divisibleByFive)
{

Also note that most C# programmers do not use "disco style" bracing. Burn the extra line and put the brace down a line.

Why is this an invalid assignment left hand side?

When you try to do this:

var b1, b2;

b1 = !b2 = true;

document.write(b1, " ", b2);

Because they are functionally equivalent you are basically doing:

var b1, b2;

!b2 = true;
b1 = true; //just the value of b2, not b2 itself

document.write(b1, " ", b2);

In the line !b2 = true, you are trying to assign an expression that evaluates to a value (the left side) to a value - that makes absolutely no sense. Think about it this way:

  • !b2 is being assigned to true. !b2 is an expression and is evaluated to a boolean value, not variable.
  • This would be analogous to doing 1 + 1 = 2. Since 1 + 1 is evaluated to a value, you can't assign that to 2, another value. You must assign a value to variable, as value-to-value assignment is semantically and logically invalid.
  • Another way to think about the above is to realize this: 1 + 1 is a value. 2 is a value. You cannot assign a value to a value, as that value already has a value. A constant such as 2 has value 2, it cannot be changed. What if we tried 1 - 1 = 2? 0, a constant and value, cannot be 2, because it is a constant.

Thus, it is semantically and logically invalid to assign a value to a value. You cannot assign 0 to 2 just as you can't assign false to true.

If you want to understand the syntax and semantics better, and why this throws a ReferenceError, you can delve into the ECMAScript® 2015 Language Specification. Per the specification:

Section 12.14.1 - Assignment Operators - Static Semantics: Early Errors

AssignmentExpression : LeftHandSideExpression = AssignmentExpression

  • It is an early Reference Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.

Where IsValidSimpleAssignmentTarget is:

Section 12.14.3 - Assignment Operators - Static Semantics: IsValidSimpleAssignmentTarget

AssignmentExpression :
YieldExpression
ArrowFunction
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression

1. Return false.

Now look back at your code: b1 = !b2 = true. b1 = !b2 is fine because it is LeftHandSideExpression = AssignmentExpression, thus returning true for IsValidSimpleAssignmentTarget. The problem arises when we check !b2 = true. If we look at the definition of LeftHandSideExpression:

Section 12.3 - Left-Hand-Side Expressions

Syntax

LeftHandSideExpression :
NewExpression
CallExpression

(You can view the definitions of NewExpression and CallExpression in the specification link above)

You can see that !b2 = true is not a valid AssignmentExpression, as it does not fit the criteria LeftHandSideExpression = AssignmentExpression. This is because !b2 is not a valid LeftHandSideExpression, also not an ObjectLiteral nor ArrayLiteral, thus IsValidSimpleAssignmentTarget returns false, throwing the ReferenceError. Note that the error is an early error, meaning it is thrown before any code is executed, as noted in @Bergi's comment.


You can combat this by doing either of the following, depending on your desired outcome:

b1 = !(b2 = true);

With parentheses, inside the parentheses takes precedence over outside. That way, b2 is assigned, and since it is true, inside the parentheses evaluates to true. Next, it's equivalent to:

b1 = !(true);

As inside the parentheses is evaluated to true as mentioned above. b1 will be the opposite of b2 as expected, and b2 will be true.

If you wanted b1 to be true and b2 to be false, restructure the statement like this:

b2 = !(b1 = true);

This way, it's the exact opposite of the above, giving b1 = true, and b2 = false.


As @Bergi mentioned in the comments, b1 is assigned the right operand, true in this case, not !b2.

Although most browsers currently do not support all features of ECMAScript 6 (2015), and instead use ECMAScript 5.1 (2011), the specification is the same for both versions. All definitions are the same, and thus the explanation is still valid.

Invalid left-hand side in assignment expression

The problem is with using string.charAt() on the left hand side. That is not possible as you're trying to assign something to the result of a function, all in the same call. Store the value of string.charAt() in an intermediary variable and it should work. Check the code below for a working example, using a slightly different approach:

function toCamelCase(str){
var stringArray = str.split('');
var indexArray = [];
stringArray.forEach(character => {
if (character === '-' || character === '_') {
var index = str.indexOf(character);
str = str.slice(0, index) + str.slice(index+1)
indexArray.push(index);
}
return character;
});
indexArray.forEach(index => {stringArray.splice(index, 1)});
return stringArray.map((char, index) => {
return indexArray.includes(index) ? char.toUpperCase() : char;
}).join('');
}

Does += return the value of the left hand side after assignment?

Assignment operators do not "return" a value: they yield one, or as the standard puts it, have one.

The value is of the left operand, although it won't be an lvalue. Here's the excerpt:

(3.3.16) An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

All of = *= /= %= += -= <<= >>= &= ^= |= are assignment operators so they behave the same way in this regard.

I can't use method Filter on ObservableCollection

should _materialCollectionView not be of type ICollectionView?

So:

private ObservableCollection<Material> _materials;
public ObservableCollection<Material> materials
{
get
{
var materials = Material.Name;
_materialCollectionView = CollectionViewSource.GetDefaultView(materials);
_materialCollectionView.Filter = _DoesMaterialMatchFileNameFilter;

return Materials;
}
}
private ICollectionView _materialCollectionView;


Related Topics



Leave a reply



Submit