How can we check for null in Scala.js?
I'm working with JavaScript library and have method that can return object or null. I've tried to use js.undefined like this
if(node != js.undefined){
global.console.log("node is object")
} else global.alert("Please select node.")
But this doesn't work
According to the docs, you can simply do:
if (node != null) {
global.console.log("node is object")
} else global.alert("Please select node.")
Check all the available types here: https://www.scala-js.org/doc/interoperability/types.html
Related
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;
}
as you maybe seen before in Effective Dart: Usage
(https://dart.dev/guides/language/effective-dart/usage)
you see :
optionalThing?.isEnabled ?? false;
I know val??other is an alternative of val == null ? other : val
but I don't understand what is ?.
The ?. operator is part of the null-aware operators. This is used in the following context:
if(object != null)
{
object.method1();
}
The above can be written as object?.method1();
So a code bool isEnabled = optionalThing?.isEnabled ?? false; will translate to following:
bool isEnabled;
if(optionalThing != null)
isEnabled = optionalThing.isEnabled;
else
isEnabled = false;
That question mark is for optionals. You can find this in swift, Kotlin and typescript as well.
Following your example optionalThing?.isEnabled is the same as:
optionalThing == null ? null : optionalThing.isEnabled;
This lets you call a method or property of an object without having to check whether the object is null. In case the object is null it would return null instead of crashing and that property or method would not be called.
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.
I have the following matcher:
Example.of(
user,
ExampleMatcher.matching()
.withMatcher("name", contains().ignoreCase())
.withMatcher("phoneNumber", contains())
)
It works fine except null values. For example, it doesn't return the users whose phone number is NULL.
I have tried to following to include the NULL values but it didn't work:
Example.of(
user,
ExampleMatcher.matching()
.withMatcher("name", contains().ignoreCase())
.withIncludeNullValues()
.withMatcher("phoneNumber", contains())
.withIncludeNullValues()
)
The generated SQL is the following:
select
user0_.id as id1_9_,
user0_.document_expiry_date as document2_9_,
user0_.document_type as document3_9_,
user0_.document_url as document4_9_,
user0_.email as email5_9_,
user0_.name as name6_9_,
user0_.phone_number as phone_nu7_9_
from
user user0_
where
(lower(user0_.name) like ?)
and (user0_.id is null)
and (user0_.document_type is null)
and (user0_.document_url is null)
and (user0_.email is null)
and (user0_.phone_number like ?)
and (user0_.document_expiry_date is null)
How can I configure it to include rows with NULL columns as well?
Confronted the same problem, but I think there is no way to accomplish this goal. Here is the source code of method withMatcher:
public ExampleMatcher withMatcher(String propertyPath, ExampleMatcher.GenericPropertyMatcher genericPropertyMatcher) {
Assert.hasText(propertyPath, "PropertyPath must not be empty!");
Assert.notNull(genericPropertyMatcher, "GenericPropertyMatcher must not be empty!");
ExampleMatcher.PropertySpecifiers propertySpecifiers = new ExampleMatcher.PropertySpecifiers(this.propertySpecifiers);
ExampleMatcher.PropertySpecifier propertySpecifier = new ExampleMatcher.PropertySpecifier(propertyPath);
if (genericPropertyMatcher.ignoreCase != null) {
propertySpecifier = propertySpecifier.withIgnoreCase(genericPropertyMatcher.ignoreCase);
}
if (genericPropertyMatcher.stringMatcher != null) {
propertySpecifier = propertySpecifier.withStringMatcher(genericPropertyMatcher.stringMatcher);
}
if (genericPropertyMatcher.valueTransformer != null) {
propertySpecifier = propertySpecifier.withValueTransformer(genericPropertyMatcher.valueTransformer);
}
propertySpecifiers.add(propertySpecifier);
return new ExampleMatcher(this.nullHandler, this.defaultStringMatcher, propertySpecifiers, this.ignoredPaths, this.defaultIgnoreCase, this.mode);
}
this method returns a ExampleMatcher with the 'global' nullHandler which applied to all the fields. That means, you can't specify a different nullHander for some special fields.
You can implements JpaSpecificationExecutor<T> in your repository and use findAll(Specification specification), and set like param:
//My solution, create a specification with predicate and add example.
public Specification<MaestroPlasticoTebca> specificationAttributeNull(boolean isNull, Example<MaestroPlasticoTebca> example, String attributeName) {
return (root, query, builder) -> {
final List<Predicate> predicates = new ArrayList<>();
if (isNull) {
predicates.add(builder.isNull(root.get(attributeName)));
} else {
predicates.add(builder.isNotNull(root.get(attributeName)));
}
predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));
return builder.and(predicates.toArray(new Predicate[0]));
};
}
And use it:
Example example = Example.of(
user,
ExampleMatcher.matching()
.withMatcher("name", contains().ignoreCase())
);
repository.findAll(specificationAttributeNull(true, example, "phoneNumber"));
In a many-to-many relationship between File and Category I want to check if a file exists and if so, if it has any categories (because there's a chance it may not have any) :
public bool existsInDBAndHasCategories(string path)
{
using (WinFileContextContainer c = new WinFileContextContainer())
{
return c.File.Any((o => o.path == path));
}
}
This checks if a file with this path has a record in the database. I got this from a thread on this site. Truth be told I am still not good with LINQ and lambdas, so I don't know how to extend it to give me BOOLEAN for any categories as well. Thanks in advance for the time.
You just have to add another condition to your method (Assuming you have defined Categories as a list of Category in File class) :
return c.File.Any((o => o.path == path && o.Categories.Any()));
If you are not familiar with Lamba, start learning simple LinQ, before you move on to lambda inside Linq queries.
You code shoud be like this:
public bool existsInDBAndHasCategories(string path)
{
using (WinFileContextContainer c = new WinFileContextContainer())
{
var query = from f in c.File
where f.Path == path &&
(f.Categories != null || f.Categories.Count != 0)
select f;
return (f.Count != 0)
}
}