I have an if block as given below:
if (this.totalTenants === 1) {
this.newTenants.tenant2 = Object.assign({ name: null, number: null }, this.emptyTenant);
this.newTenants.tenant3 = Object.assign({ name: null, number: null }, this.emptyTenant);
this.newTenants.tenant4 = Object.assign({ name: null, number: null }, this.emptyTenant);
this.newTenants.tenant2 = this.emptyTenant;
this.newTenants.tenant3 = this.emptyTenant;
this.newTenants.tenant4 = this.emptyTenant;
this.newTenants.rentAmount = 3200;
}
But when the value of this.totalTenants is 1 it doesn't go into the if block.
I'm working on Angular 6 with typescript.
If I if (this.totalTenants == 1) double equals sign ==
then the if block is executed but I get the error as displayed below:
[tslint] == should be === (triple-equals)
The difference between == and === operators is that the first make an automatic cast to facilitate comparison, the second one does not cast anything.
So if you try to compare two number values, but one of them is a string representation of the number, comparison fails with === operator.
Probably you are using a string value like '1', to check this you can execute something like this:
console.log(typeof this.totalTenants)
If it resulsts in a string you should change your operator to == or cast that value to a number prepending the variable with + like this:
if (+this.totalTenants === 1) {
This is my code for true on everything but empty string, null and false:
if (routeinfo["no_route"] == "" || routeinfo["no_route"] == null || routeinfo["no_route"] == false) {
// do sth ...
}
This is my code for true on everything but empty string, null, false or zero:
if (routeinfo["no_route"] == "" || routeinfo["no_route"] == null || routeinfo["no_route"] == false || routeinfo["no_route"] == 0) {
// do sth...
}
How can I write this shorter in Dart? Or is it not possible?
If your requirement was simply empty or null (like mine when I saw this title in a search result), you can use Dart's safe navigation operator to make it a bit more terse:
if (routeinfo["no_route"]?.isEmpty ?? true) {
//
}
Where
isEmpty checks for an empty String, but if routeinfo is null you can't call isEmpty on null, so we check for null with
?. safe navigation operator which will only call isEmpty when the object is not null and produce null otherwise. So we just need to check for null with
?? null coalescing operator
If your map is a nullable type then you have to safely navigate that:
if (routeinfo?["no_route"]?.isEmpty ?? true) {
//
}
You could do
if (["", null, false, 0].contains(routeinfo["no_route"])) {
// do sth
}
Late 2020 Update
Summary
This answer holds true, except for isNull and isNotNull. They no longer provide type promotion when Null Safety is introduced in dart/flutter in the future.
Other helpers like isNullOrEmpty do not provide type promotion, as they are in a different (sub-)scope compared to callsite.
My personal opinion, is that you can drop isNull and isNotNull but keep other helpers as you shouldn't expect them to do type promotion for you.
Explanation
This is because Null Safety was finally introduced in Dart/Flutter. But as of October 2020, this feature is still not available for stable releases on dart/flutter. Check out the quick guide Null Safety or the thorough Understanding Null Safety.
Null Safety in Dart/Flutter should be similar to Swift (Optional) and Kotlin (Nullable Types, Non-Nullable Types).
Demonstration
Here's a demonstration why encapsulation/helper-getter of isNull (== null) and isNotNull (!= null) is a very big problem:
// Promotion works
int definitelyInt(int? aNullableInt) {
if (aNullableInt == null) { // Promote variable `aNullableInt` of Nullable type `int?` to Non-Nullable type `int`
return 0;
}
return aNullableInt; // Can't be null! This variable is promoted to non-nullable type `int`
}
When "Null Safety" is shipped in the dart release you are using, the type promotion in above code works! HOWEVER:
// Promotion does NOT work!!!
int definitelyInt(int? aNullableInt) {
if (aNullableInt.isNull) { // does NOT promote variable `aNullableInt` of Nullable type `int?`
return 0;
}
return aNullableInt; // This variable is still of type `int?`!!!
}
The above doesn't work, because the null check == null and != null are encapsulated in a sub-scope (different stack frame) and not inferred to have this "promotion" effect within definitelyInt scope.
Early 2020 Update
Here's a modified version using getters instead of instance/class methods and covering whitespaces, isNull, and isNotNull.
Second Update
It also accounts for empty lists and maps now!
Third Update
Added private getters for safety and modularity/maintainability.
Fourth Update
Updated the answer to fix a particular problem with Map, it's not correctly being handled when empty! Because Map is not an Iterable. Solved this issue by introducing _isMapObjectEmpty U
Solution
extension TextUtilsStringExtension on String {
/// Returns true if string is:
/// - null
/// - empty
/// - whitespace string.
///
/// Characters considered "whitespace" are listed [here](https://stackoverflow.com/a/59826129/10830091).
bool get isNullEmptyOrWhitespace =>
this == null || this.isEmpty || this.trim().isEmpty;
}
/// - [isNullOrEmpty], [isNullEmptyOrFalse], [isNullEmptyZeroOrFalse] are from [this StackOverflow answer](https://stackoverflow.com/a/59826129/10830091)
extension GeneralUtilsObjectExtension on Object {
/// Returns true if object is:
/// - null `Object`
bool get isNull => this == null;
/// Returns true if object is NOT:
/// - null `Object`
bool get isNotNull => this != null;
/// Returns true if object is:
/// - null `Object`
/// - empty `String`s
/// - empty `Iterable` (list, set, ...)
/// - empty `Map`
bool get isNullOrEmpty =>
isNull ||
_isStringObjectEmpty ||
_isIterableObjectEmpty ||
_isMapObjectEmpty;
/// Returns true if object is:
/// - null `Object`
/// - empty `String`
/// - empty `Iterable` (list, map, set, ...)
/// - false `bool`
bool get isNullEmptyOrFalse =>
isNull ||
_isStringObjectEmpty ||
_isIterableObjectEmpty ||
_isMapObjectEmpty ||
_isBoolObjectFalse;
/// Returns true if object is:
/// - null `Object`
/// - empty `String`
/// - empty `Iterable` (list, map, set, ...)
/// - false `bool`
/// - zero `num`
bool get isNullEmptyFalseOrZero =>
isNull ||
_isStringObjectEmpty ||
_isIterableObjectEmpty ||
_isMapObjectEmpty ||
_isBoolObjectFalse ||
_isNumObjectZero;
// ------- PRIVATE EXTENSION HELPERS -------
/// **Private helper**
///
/// If `String` object, return String's method `isEmpty`
///
/// Otherwise return `false` to not affect logical-OR expression. As `false` denotes undefined or N/A since object is not `String`
bool get _isStringObjectEmpty =>
(this is String) ? (this as String).isEmpty : false;
/// **Private helper**
///
/// If `Iterable` object, return Iterable's method `isEmpty`
///
/// Otherwise return `false` to not affect logical-OR expression. As `false` denotes undefined or N/A since object is not `Iterable`
bool get _isIterableObjectEmpty =>
(this is Iterable) ? (this as Iterable).isEmpty : false;
/// **Private helper**
///
/// If `Map` object, return Map's method `isEmpty`
///
/// Otherwise return `false` to not affect logical-OR expression. As `false` denotes undefined or N/A since object is not `Map`
bool get _isMapObjectEmpty => (this is Map) ? (this as Map).isEmpty : false;
/// **Private helper**
///
/// If `bool` object, return `isFalse` expression
///
/// Otherwise return `false` to not affect logical-OR expression. As `false` denotes undefined or N/A since object is not `bool`
bool get _isBoolObjectFalse =>
(this is bool) ? (this as bool) == false : false;
/// **Private helper**
///
/// If `num` object, return `isZero` expression
///
/// Otherwise return `false` to not affect logical-OR expression. As `false` denotes undefined or N/A since object is not `num`
bool get _isNumObjectZero => (this is num) ? (this as num) == 0 : false;
}
Assumptions
This presumes Dart 2.7 or above to support Extension Methods.
Usage
The above are two Extension classes. One for Object and one for String. Put them in a file separately/together and import the files/file at callsite file.
Description
Coming from Swift, I tend to use extensions like user #Benjamin Menrad's answer but with getter instead of method/function when applicable -- mirroring Dart's computed properties like String.isEmpty.
Coming from C#, I like their String's helper method IsNullOrWhiteSpace.
My version merges the above two concepts.
Naming
Rename the Extension classes whatever you like. I tend to name them like this:
XYExtension
Where:
X is File/Author/App/Unique name.
Y is name of Type being extended.
Name examples:
MyAppIntExtension
DartDoubleExtension
TextUtilsStringExtension
OHProviderExtension
Criticism
Why private getters instead of simple
this == null || this == '' || this == [] || this == 0 || !this
I think this is safer as it first casts the object to the right type we want to compare its value to.
More modular as changes are central within the private getters and any modification is reflected everywhere.
If type check fails within the private getter, we return false which doesn't affect the outcome of the root logical-OR expression.
I would write a helper function instead of doing everything inline.
bool isNullEmptyOrFalse(Object o) =>
o == null || false == o || "" == o;
bool isNullEmptyFalseOrZero(Object o) =>
o == null || false == o || 0 == o || "" == o;
That avoids the repeated lookup (like the contains operation), but it is much more readable. It also doesn't create a new List literal for each check (making the list const could fix that).
if (isNullEmptyOrFalse(routeinfo["no_route"])) { ... }
When struggling with making something short and readable, making a well-named helper function is usually the best solution.
(Addition: Now that Dart has extension methods, it's possible to add the functionality as methods or getters that are seemingly on the object, so you can write value.isNullOrEmpty directly).
As coming from Android and Kotlin, I prefer extension methods over a static helper method. And with Dart 2.7 you can now use that as well:
extension Extension on Object {
bool isNullOrEmpty() => this == null || this == '';
bool isNullEmptyOrFalse() => this == null || this == '' || !this;
bool isNullEmptyZeroOrFalse() =>
this == null || this == '' || !this || this == 0;
}
Now you can just call these methods from anywhere in your code:
if (anyVariable.isNullOrEmpty()) {
// do something here
}
You might need to manually import the dart class, where you put your extension methods, for example:
import 'package:sampleproject/utils/extensions.dart';
With Null safety:
Say, you have a nullable Map and a List which have nullable values in it.
Map<String, List?>? map;
List<String?>? list;
To check if the collection is neither null nor empty, you can do:
if (map?.containsKey('foo') ?? false) {
print('map is not-null, and key "foo" is present.');
}
if (list?.isNotEmpty ?? false) {
print('list is not-null and not empty');
}
For strings i like this approach:
extension NullableStringExtensions<E> on String? {
/// Returns `true` if this string is `null` or empty.
bool get isNullOrEmpty {
return this?.isEmpty ?? true;
}
/// Returns `true` if this string is not `null` and not empty.
bool get isNotNullNorEmpty {
return this?.isNotEmpty ?? false;
}
}
Credits go to the author of this package: https://pub.dev/packages/string_ext
bool isNullString(String? value) {
if (value == null || value.isEmpty ) {
return true;
} else {
return false;
}
}
and use this method like
isNullString(yourValue)
package:quiver has an isEmpty function that returns true if the argument is null or the empty string.
It's also trivial to implement such a function yourself.
In a form-component I have an observer that tests if a property is valid before to start further validations.
So I checked if the property has not yet been defined (happens at initialization f.e.)
if(typeof this.get('myProperty') !== 'undefined') {
//do smth
}
Then I realized that this.get would not return a type of 'undefined' but a string with the value undefined.
Fair enough.
BUT
console.log(this.get('myProperty'));
gives me ' undefined' instead of 'undefined' - notice the space before 'undefined'!
Is this a bug?
Or do I really have to check for ' undefined' with a space and is there a reason for that?
Ember-cli: 1.13.7
Ember: 2.0.1
How about you use Ember.isNone or Ember.isEmpty. For the opposite Ember.isPresent
Returns true if argument is null or undefined.
Ember.isNone(); // true
Ember.isNone(null); // true
Ember.isNone(undefined); // true
Ember.isNone(''); // false
Ember.isNone([]); // false
Ember.isNone(function(){}); // false
This utility function constrains the rules on Ember.none by returning false for empty string and empty arrays.
Ember.isEmpty(); // true
Ember.isEmpty(null); // true
Ember.isEmpty(undefined); // true
Ember.isEmpty(''); // true
Ember.isEmpty([]); // true
Ember.isEmpty('tobias fünke'); // false
Ember.isEmpty([0,1,2]); // false
I was surprised when I read Handlebars won't let you put a conditional with little logic like (If something === 1...) , so I'm really stuck on how to make this a Handlebar template.
if {{price_type}} == 1
Example
else if {{price_type}} == 2
{{min_price}}
else
No price
How is this dealt with in Handlebars? Thanks guys
You can do this by writing your own template helper.
Handlebars.registerHelper('conditionalHelper', function(lValue, rValue, options) {
if (lValue == rValue) {
return options.fn(this);
}
return options.inverse(this);
});
This helper will accept two values 'lValue' and 'rValue' and return true or false depending on whether these values are equal or not. We can use this helper in the example given above as follows-
{{#conditionalHelper price_type 1}}
Example
{{else}}
{{#conditionalHelper price_type 2}}
{{min_price}}
{{else}}
No price
{{/conditionalHelper}}
{{/conditionalHelper}}
The handlebars if-helper only works for boolean values. So when you want to perform conditional operations on them you need to create your own helper.
{{#ifPriceType price_type min_type}}{{/ifPriceType}}
Handlebars.registerHelper("ifPriceType",function(price_type,min_type){
if(price_type==1){ return "Example";}
else if(price_type==2){ return min_type;}
else return "No price";
});
You can even achieve in template itself like below:
if {{price_type}} == 1
Example
else
if {{price_type}} == 2
{{min_price}}
else
No price
I have a input form and I want to check for some user_name properties. For instance if username is only lowercase with numbers. I am using callback function but given only a simple string such as "a" wont return true .. I really dont understand. What am I doing wrong ??
$this->form_validation->set_rules('user_name','User name','required|callback_validate_user_name');
...
if($this->form_validation->run() !== false){
$data['main_content'] = 'pages/news_page';
$this->load->view('templates/home_body_content', $data);
} else {
echo "Damn!";
}
function validate_user_name($user_name){
if(preg_match('/a/', $user_name) === true){
return true;
}
return false;
}
First, PHP preg_match() returns 1 if the pattern matches given subject [Reference]
So use === 1 or == TRUE instead of === true.
Second, callback function should return FALSE when /a/ pattern is occurred, and return TRUE if not.