rephrase the if statement in Dart 2.0 using null - flutter

I have following statement in flutter. weight is the text from _weightController i.e. _weightController.text
int.parse(weight).toString().isNotEmpty && int.parse(weight) > 0
But in Dart 2.0 it is not working properly. For empty TextField, it is giving the error.
====== Exception caught by gesture ==============================
The following FormatException was thrown while handling a gesture:
Invalid number (at character 1)
The code block is like this.
if (int.parse(weight).toString().isNotEmpty && int.parse(weight) > 0)
return int.parse(weight) * multiplier;
else
print('Error');

As an alternative to the other answer, you can use the tryParse() method:
Like parse except that this function returns null where a similar call to parse would throw a FormatException, and the source must still not be null.
If you use this approach, you should check the return value for null:
String weight ="";
int number = int.tryParse(weight);
if (number !=null){
print(number );
}
else
print("error");
Don't forget to also check the variable for null with weight ? "" or with weight != null

Try this:
if (weight != null && weight.isNotEmpty) {
return int.tryParse(weight) * multiplier;
} else {
print("CoolTag: error");
return -1;
}

Related

NullReferenceException when gamepad is disconnected

I'm using New Input system on my game and I'm having this error
NullReferenceException: Object reference not set to an instance of an object
PauseMenu.Update ()
pointing to this line:
if (gamepad.startButton.wasPressedThisFrame || keyboard.pKey.wasPressedThisFrame)
whenever the gamepad is not connected.
void Update()
{
var gamepad = Gamepad.current;
var keyboard = Keyboard.current;
if (gamepad == null && keyboard == null)
return; // No gamepad connected.
if (gamepad.startButton.wasPressedThisFrame || keyboard.pKey.wasPressedThisFrame)
{
if (GameIsPaused)
{
Resume();
}
else
{
Pause();
}
}
}
How can I fix this?
The issue is that the exit condition requires that both keyboard and gamepad are null. In the case that gamepad is null and keyboard is not (or the other way around), an attempt is made to access a member of the null object.
You can resolve the issue by comparing each object against null before accessing its properties.
if ((gamepad != null && gamepad.startButton.wasPressedThisFrame) ||
(keyboard != null && keyboard.pKey.wasPressedThisFrame)
)
{
// Pause / Resume
}
You could also use the null conditional operator ? in each condition. When the preceding object is null, the resulting value is null. Then using the null coalescing operator ?? we convert this null value to a bool (false in this case because a null button cannot be "pressed").
if (gamepad?.startButton.wasPressedThisFrame ?? false ||
keyboard?.pKey.wasPressedThisFrame ?? false)

Can I simplify a condition with short-circuit call chain in Dart?

Can this code snippet be simplified on the second line?
From:
GetBuilder<ProductController>(builder: (productController) {
return productController.reviewedProductList == null || productController.reviewedProductList.length != 0
? CategoryDrinksView(productController: productController, isPopular: true)
: SizedBox();
})
To:
GetBuilder<ProductController>(builder: (productController) {
return productController.reviewedProductList?.length != 0
? CategoryDrinksView(productController: productController, isPopular: true)
: SizedBox();
})
The IDE doesn't return any errors and everything seems to work, but I would like to know if this is common in Dart and can be considered good practice.
I don't think it's a good idea. You may get a 'NoSuchMethodError: The getter 'length' was called on null' error, if the value of reviewedProductList was null. So keep the double checking

Is there "!." operator in dart (flutter)?

Flutter source files contains many times code similar to this:
#override
double computeMinIntrinsicWidth(double height) {
if (child != null)
return child!.getMinIntrinsicWidth(height);
return 0.0;
}
Please explain "!." I can't find it on list of dart operators.
A postfix exclamation mark (!) takes the expression on the left and casts it to its underlying non-nullable type. So it changes:
String toString() {
if (code == 200) return 'OK';
return 'ERROR $code ${(error as String).toUpperCase()}';
}
to something like this:
String toString() {
if (code == 200) return 'OK';
return 'ERROR $code ${error!.toUpperCase()}';
}
You can read more about null safety in this document.
It's the "(not)null assertion operator" which becomes part of Dart with the Null Safety feature in the next release.

Set custom filters for boost log sink with custom attribute & severity level

I have a log setup in which I have 2 types of log messages:
1 based solely on severity level
1 based solely on a custom tag attribute
These attributes are defined as follows:
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", trivial::severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
I want to create a filter function that allows a message to be added to my log based on either of the 2 criteria (note that the log messages based on the custom tag attribute are always printed with severity level info, based on the trivial logger's severity levels).
So I want to have a filter, which allows a message based on if a message has the custom tag, and if it does not have it, based on the severity of the message.
I have tried to have a relative simple filter which does the following:
sink_->set_filter(
trivial::severity >= severityLevel
|| (expr::has_attr(tag_attr) && tag_attr == "JSON" && logJson_)
);
But as it is possible that the severityLevel can be either Debug, Info, Warning, Error or Fatal, if the level is configured as either Debug or Info, the custom tag attribute is ignored by the filter.
I have tried using a c++11 lambda, as following:
sink_->set_filter([this, severityLevel](const auto& attr_set) {
if (<condition for custom tag first>) {
return true;
} else if (<condition for severity level second>) {
return true;
} else {
return false;
}
});
But then I don't have an idea on how to actually check for my conditions. I have tried the following:
if (attr_set["Tag"].extract<std::string>() == "JSON" && logJson_) {
return true;
} else if (attr_set["Severity"].extract<trivial::severity_level>() >= severityLevel) {
return true;
} else {
return false;
}
But the compiler throws several errors about this:
Core/Source/Log/Logger.cpp: In lambda function:
Core/Source/Log/Logger.cpp:127:48: error: expected primary-expression before '>' token
if (attr_set["Tag"].extract<std::string>() == "JSON" && logJson_) {
^
Core/Source/Log/Logger.cpp:127:50: error: expected primary-expression before ')' token
if (attr_set["Tag"].extract<std::string>() == "JSON" && logJson_) {
^
Core/Source/Log/Logger.cpp:129:72: error: expected primary-expression before '>' token
} else if (attr_set["Severity"].extract<trivial::severity_level>() >= severityLevel) {
^
Core/Source/Log/Logger.cpp:129:74: error: expected primary-expression before ')' token
} else if (attr_set["Severity"].extract<trivial::severity_level>() >= severityLevel) {
^
Core/Source/Log/Logger.cpp: In lambda function:
Core/Source/Log/Logger.cpp:134:5: error: control reaches end of non-void function [-Werror=return-type]
});
^
cc1plus: all warnings being treated as errors
scons: *** [obj/release/Core/Source/Log/Logger.os] Error 1
====5 errors, 0 warnings====
I have been scouring the boost log documentation about extracting the attributes myself, but I cannot find the information I need.
EDIT:
For posterity, I'll add how I've solved my issue (with thanks to the given answer by Andrey):
sink_->set_filter([this, severityLevel](const auto& attr_set) {
if (attr_set[tag_attr] == "JSON") {
return logJson_;
} else if (attr_set[severity] >= severityLevel) {
return true;
} else {
return false;
}
});
The filter can be written in multiple ways, I will demonstrate a few alternatives.
First, using expression templates you can write it this way:
sink_->set_filter(
(expr::has_attr(tag_attr) && tag_attr == "JSON" && logJson_) ||
trivial::severity >= severityLevel
);
Following the normal short-circuiting rules of C++, the tag attribute will be tested first and if that condition succeeds, the severity will not be tested. If the tag is not present or not JSON or logJson_ is not true, then severity level is tested.
Note that the filter above will save copies of its arguments (including logJson_ and severityLevel) at the point of construction, so if you change logJson_ later on the filter will keep using the old value. This is an important difference from your later attempts with C++14 lambdas, which access logJson_ via the captured this pointer. If you actually want to save a reference to your member logJson_ in the filter, you can use phoenix::ref:
sink_->set_filter(
(expr::has_attr(tag_attr) && tag_attr == "JSON" && boost::phoenix::ref(logJson_)) ||
trivial::severity >= severityLevel
);
However, you should remember that the filter can be called concurrently in multiple threads, so the access to logJson_ is unprotected. You will have to implement your own thread synchronization if you want to update logJson_ in run time.
Barring multithreading issues, your second attempt with a lambda is almost correct. The compiler is complaining because the lambda function is a template, and the result of attr_set["Tag"] expression depends on one of the template parameters (namely, the type of attr_set). In this case, the programmer has to qualify that the following extract<std::string>() expression is a template instantiation and not a sequence of comparisons. This is done by adding a template keyword:
if (attr_set["Tag"].template extract<std::string>() == "JSON" && logJson_) {
return true;
} else if (attr_set["Severity"].template extract<trivial::severity_level>() >= severityLevel) {
return true;
} else {
return false;
}
Note that you could use a standalone function to the same effect, which wouldn't require the template qualification:
if (boost::log::extract<std::string>("Tag", attr_set) == "JSON" && logJson_) {
return true;
} else if (boost::log::extract<trivial::severity_level>("Severity", attr_set) >= severityLevel) {
return true;
} else {
return false;
}
Finally, the preferred way to extract attribute values is to leverage attribute keywords, which you declared previously. Not only this allows to avoid the template qualification quirk but it also removes a lot of code duplication.
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", trivial::severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
if (attr_set[tag_attr] == "JSON" && logJson_) {
return true;
} else if (attr_set[severity] >= severityLevel) {
return true;
} else {
return false;
}
The attribute value name and type are inferred from the keyword declaration in this case. This use of attribute keywords is documented at the end of this section.

How can I get an alert if a specific url substring is present and nothing if null

function getCode() {
if (window.location.href.indexOf("?discount=")) {
var url = (document.URL);
var id = url.substring(url.lastIndexOf('=') + 1);
window.alert(id);
return true;
} else {
return false;
}
}
Purpose: When people go to our "Service Request" page using a QR code that has a substring of ?discount=1234. I have been testing by creating an alert box with the discount code showing. Eventually I want to be able to populate that "1234" automatically into a "Discount Code:" text field on page load.
The above is a mixture of a few suggestions when I researched it.
Result: Going to example.com/serviceRequest.html?discount=1234 gives me the appropriate alert "1234", as I want... Going to example.com/serviceRequest.html gives me the alert http://example.com/serviceRequest.html, but I don't want anything to happen if "?discount=" is null.
Any suggestions?
indexOf returns -1 if the search pattern doesn't exist. In JavaScript, anything not a 0 or false or undefined is considered true.
So your line of:
if(window.location.href.indexOf("?discount=")) {
Would better search as:
if(window.location.href.indexOf("?discount=") > -1) {
Try changing your if-statement to:
if(window.location.href.indexOf("?discount=") != -1)
Look up the documentation for ".indexOf". It returns -1 for not found and >= 0 if it is found.
...indexOf("?discount=") >= 0
substring and indexOf return -1 if the text is not found, so you can test for this. E.g.
function getCode() {
if(window.location.href.indexOf("?discount=") != -1) {
var url = (document.URL);
var id = url.substring(url.lastIndexOf('=') + 1);
window.alert(id);
return true;
}
else {
return false;
}
}
You just need to test the indexOf value:
function getCode() {
if (window.location.href.indexOf("?discount=") !== -1) {
var url = (document.URL);
var id = url.substring(url.lastIndexOf('=') + 1);
window.alert(id);
return true;
}
else {
return false;
}
}
So the quick and dirty answer would be
var discount = window.location.search.split("?discount=")[1];
alert(discount);
But this doesn't take into account the occurence of other query string parameters.
You'll really want to parse all the query parameters into a hash map.
This article does a good job of showing you a native and jQuery version.
http://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html