? operator to avoid NoSuchMethodError in dart - dart

I saw a video of someone try to avoid NoSuchMethodError by using ? operator . here's the code:
/*1*/ void main () {
/*2*/ var v = vu() ;
/*3*/ var f = v.casting() ;
/*4*/ f.tbu ;
/*5*/}
show error on line 4
Unhandled exception: NoSuchMethodError: The
getter 'tbu' was called on null. Receiver: null Tried calling: tbu
but he used the ? operator :
/*1*/ void main () {
/*2*/ var v = vu() ;
/*3*/ var f = v.casting() ;
/*4*/ f?.tbu ;
/*5*/}
run without problem .
My question is what is the ? operator ??

The question mark placed before the dot allows conditional property access, which guards against trying to access a property or method of an object that might be null:
myObject?.someProperty
is equivalent to the following:
(myObject != null) ? myObject.someProperty : null
This is similar to optional chaining in JavaScript.

Related

I know it is not null, but Dart doesn't know that. How do I tell it?

The code Dart is complaining about:
Map<String,int> get_frequency(String text) {
Map<String,int> retval = {};
for (int i = 0; i<text.length; ++i) {
retval[text[i]] = retval[text[i]] ?? 0;
retval[text[i]]++; //<---- this is where dart is complaining.*
}
return retval;
}
void main() {
const paragraphOfText = 'Once upon a time there was a Dart programmer who '
'had a challenging challenge to solve. Though the challenge was great, '
'a solution did come. The end.';
var data = get_frequency(paragraphOfText);
print(data);
}
Obviously the line marked with (*) can not be null, so how do I tell that to Dart? I tried the null assertion operator (!), but that didn't work.
Null Safety is enabled.
Error message:
challenge2.dart:5:20: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
retval[text[i]]++;
^
challenge2.dart:5:20: Error: A value of type 'num' can't be assigned to a variable of type 'int'.
retval[text[i]]++;
^
A possible solution is to change the line
retval[text[i]]++; //<---- this is where dart is complaining.*
into
retval[text[i]] = retval[text[i]]! + 1;
Just figured it out.

Instancing Nested Object (Dart)

On trying to assign values to Nested Object Properties,Dart treats the Nested Object(class OperandRange) as null.
Default values have been assigned to the Nested Object Properties but the issue exists.
In the case below Nested Object Class OperandRange should be assigned minimum and maximum values but dart considers it to the Null.
How to resolve this?
Code
import 'dart:io';
//Nested Object Class
class OperandRange{
double _minValue = 0;
double _maxValue = 10;
OperandRange(this._minValue , this._maxValue);
double get minValue => _minValue;
double get maxValue => _maxValue;
set minValue(double _val){
_minValue = (_val) ;
}
set maxValue(double _val){
_maxValue = (_val) ;
}
}
class OperationData{
List<OperandRange> operandList = [];//Nested Object
List<String> operatorList = [] ;
OperationData({this.operandList, this.operatorList});
}
void main(){
int _operationCount = 2;
OperationData _operation = OperationData();
for(int _index = 0 ; _index < _operationCount ; _index++) {
stdout.write(" Operation $_index - Name(string): ");
_operation.operatorList[_index] = stdin.readLineSync();
//Null Object
stdout.write(" Operand $_index - Minimum Value (double) : ");
_operation.operandList[_index]._minValue =
double.parse(stdin.readLineSync());
stdout.write(" Operand $_index - Maximum Value (double): ");
_operation.operandList[_index]._maxValue =
double.parse(stdin.readLineSync());
}
}
Error
Operation 0 - Name(string): Add
Unhandled exception:
NoSuchMethodError: The method '[]=' was called on null.
Receiver: null
Tried calling: []=(0, "Add")
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 main (1.dart:41:28)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
Process finished with exit code 255
Here is what's happening.
You initialize operandList with a nested list. But this never has any effect because you also initialize it in OperationData constructor. Once you mention it in constructor arguments, it will either be set to a value you pass to constructor, or set to null if you do not pass this argument to constructor.
For your purpose you may remove constructor altogether as you never pass anything to it. Then your [] defaults will stand.
Otherwise, if in some cases you need to initialize it with a custom list, you may do it like this:
class OperationData{
List<OperandRange> operandList;
List<String> operatorList;
OperationData({
List<OperandRange> operandList,
List<String>operatorList,
}) :
this.operandList = operandList ?? <OperandList>[],
this.operatorList = operatorList ?? <String>[]
;
}
The same goes for your OperandRange class. 0 and 10 defaults will never be used as the constructor requires explicit values. By the way, I do not see OperandRange creation at all. The list stays empty. You will catch a next error when trying to access an index out of bounds when you fix the first error.
Also you should upgrade to Dart 2.12 if possible. It introduced null-safety that would show you this error at compile time.

How to create inline if without else case

Does Dart support a syntax to have an inline if without an else case? I sometimes find myself in a situation to create a flutter layout where this might be really helpful
new Row(children: <Widget>[
new Text(item.name),
item.name2 != null ? new Text(item.name2) : new Container(),
]
In this example the empty container is unnecessary so I was hoping for something like this:
new Row(children: <Widget>[
new Text(item.name),
item.name2 != null ? new Text(item.name2),
]
there is no inline if without else
but in your case you're using if only to check only if it's null or not
dart have :
x = someVar ?? 0
here dart checks if someVar == null ? if true sets x value to 0, if false sets it to someVar value
but flutter will never let you add null to it's widget tree, so your can't use it in row/col
You can do this:
myVar == null ? 0 : myVar
If myVar is null then is 0, else then myVar
If you need to call a function you can use like this:
String s; //null
s == null ? print("if shorthand working") : {};
For variable assignment:
String c = "not null value";
String b; //null
var a = b ?? c;
Now a = c.
Visual Studio Code tip: add this to ignore linting for a line
// ignore: unnecessary_statements
In general, the "inline if" can be written in darts as follows:
<condition> ? <expression 1> : <expression 2>
So that if <condition> evaluates to True, then <expression 1> is returned and otherwise <expression 2>.
For example:
result = myVar == null ? 0 : myVar ;
// if myVar is null -> result = 0
// if myVar is not null -> result = myVar
There is actually plans to include a similar feature into the Dart language itself.
For a preview of how it would look like, take a look at this article by Remi
https://medium.com/flutter-community/quick-tip-sync-a-taste-of-the-future-9be4cd6993f4
And some accompanying Github issues
https://github.com/flutter/flutter/issues/17862
https://github.com/dart-lang/language/issues/47
https://github.com/dart-lang/language/issues/78

Service Fabric reliable state and F# default GetHashCode issue

I having an issue when trying to update a SF stateful service after updating a child object of the service state. The upgrade fails to pass the 1st upgrade domain with a 'package activation' error. Digging around in the event viewer on the offending node gives the below exception:
Errormsg=TStore.OnApplyAddAsync: Unexpected exception System.NullReferenceException: Object reference not set to an instance of an object.
at xxx.DataChildObject.GetHashCode(IEqualityComparer comp)
at xxx.Data.GetHashCode(IEqualityComparer comp)
at xxx.Data.GetHashCode() in C:\Users\xxx\Source\Repos\xxx\xxx\xxx.Core\Domain.fs:line 17
at System.Fabric.Store.TStore`5.OnApplyAdd(TransactionBase txn, MetadataOperationData metadataOperationData, RedoUndoOperationData operationRedoUndo, Boolean isIdempotent, String applyType) Assert=System.Exception: at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
The change to the 'DataChildObject' was to add a new field that is a tuple of 2 doubles.
I understand that F# is automatically generating equality methods and these must be triggered during SF state and that due to datacontact serialisation these are null during the GetHashCode check.
I don't understand exactly when this check is being performed or why though?
As a test i tried overriding the GetHasCode method on my DataChildObject, but this didn't change the error i get when trying to upgrade my service.
[<DataContract>]
type DataChildObject =
class
[<DataMember(IsRequired=false,Name="Value1")>] val mutable Value1 : float * float
[<DataMember(IsRequired=false,Name="Value2")>] val mutable Value2 : float * float
[<DataMember(IsRequired=false,Name="NewValue")>] val mutable NewValue : float * float
new (v1,v2) = {Value1=v1;Value2=v2;NewValue=1.0,1.0}
override this.GetHashCode() =
let value1 = if (box this.Value1 = null) then 1 else this.Value1.GetHashCode()
let value2 = if (box this.Value2 = null) then 1 else this.Value2.GetHashCode()
let newValue = if (box this.NewValue = null) then 1 else (this.NewValue).GetHashCode()
value1+value2+newValue
end
I expect these domain objects to change more in the near future so any help in understanding exact how to get past or avoid this issue is helpful.
Thanks

Retrieve LHS/RHS value of operator

I'm looking to do something similar to this how to get integer variable name and its value from Expr* in clang using the RecursiveASTVisitor
The goal is to first retrieve all assignment operations then perform my own checks on them, to do taint analysis.
I've overridden the VisitBinaryOperator as such
bool VisitBinaryOperator (BinaryOperator *bOp) {
if ( !bOP->isAssignmentOp() ) {
return true;
}
Expr *LHSexpr = bOp->getLHS();
Expr *RHSexpr = bOp->getRHS();
LHSexpr->dump();
RHSexpr->dump();
}
This RecursiveASTVisitor is being run on Objective C codes, so I do not know what the LHS or RHS type will evaluate to (could even be a function on the RHS?)
Would it be possible to get the text representation of what is on the LHS/RHS out from clang in order to perform regex expression on them??
Sorry, I found something similar that works for this particular case.
Solution:
bool VisitBinaryOperator (BinaryOperator *bOp) {
if ( !bOP->isAssignmentOp() ) {
return true;
}
Expr *LHSexpr = bOp->getLHS();
Expr *RHSexpr = bOp->getRHS();
std::string LHS_string = convertExpressionToString(LHSexpr);
std::string RHS_string = convertExpressionToString(RHSexpr);
return true;
}
std::string convertExpressionToString(Expr *E) {
SourceManager &SM = Context->getSourceManager();
clang::LangOptions lopt;
SourceLocation startLoc = E->getLocStart();
SourceLocation _endLoc = E->getLocEnd();
SourceLocation endLoc = clang::Lexer::getLocForEndOfToken(_endLoc, 0, SM, lopt);
return std::string(SM.getCharacterData(startLoc), SM.getCharacterData(endLoc) - SM.getCharacterData(startLoc));
}
Only thing I'm not very sure about is why _endLoc is required to compute endLoc and how is the Lexer actually working.
EDIT:
Link to the post I found help Getting the source behind clang's AST

Resources