Useless Tips for Dart you probably never need. (Part 3)
Tags: programming, flutter, dart, productivity
Published: 2022-01-13 17:03:58

There exist a lot of great articles highlighting the most useful tips and tricks for Flutter and Dart. They provide great value for both beginners and advanced developers. 

This article is not one of them.

This is about the useless tips, the weird quirks, the boring facts and not needed tricks. They are either so absurd you won't ever need them, or so abstruse you don't wish to need them. But they deserve some love, too.

---

## NoSuchMethod


On our list of things we can use how they are definitely not intended, there is one more we haven't covered yet. In Dart there exists the special `noSuchMethod(Invocation i)` method that we can override in any custom class. As the name suggests, this method will be called when we try to access an instance member that does not exists.

For example take the class `Person` with only one method `greet()` and the overridden `noSuchMethod(Invocation i)`. When we try to do `person.hello()` instead of throwing an error, our `noSuchMethod(Invocation i)` gets called with an `Invocation` object containing all information about the failed invocation, like name of the method or any parameters. It also supports getters and setters. Just note that the `person` variable has to have the type `dynamic` otherwise the compiler would complain.


### JsObject

Here's my pitch: In Javascript you can access properties of any object either using `object['myProp']` or directly via `object.myProp`. In Dart you can only do one at a time, either with a `Map` or a custom class that defines `myProp` as a field or getter/setter. You cannot however access an arbitrary property dynamically and extend an object at runtime. 

Except with `noSuchMethod` we can. We would have a class that internally just wraps a `Map`, but externally uses `noSuchMethod` to catch any property access using getters and setters.

You probably know that there are several reasons why this is a very bad idea to do. For instance it is a poor way to completely disregard any type safety that comes with Dart. So let's do it anyways!

First we define our `JsObject` class. It just wraps a `Map<String, dynamic>` and overrides both `noSuchMethod` and `toString`.

```dart
class JsObject {
  final Map<String, dynamic> map = {};
  
  @override
  dynamic noSuchMethod(Invocation i) { 
    // TODO
  }  
  
  @override
  String toString() {
    return map.toString();
  }
}
```

We then fill in the implementation for `noSuchMethod()` which is actually pretty straight forward:

```dart
@override
dynamic noSuchMethod(Invocation i) { 
  if (i.isGetter) {
    return map[i.memberName.name];
  } else if (i.isSetter) {
    map[i.memberName.name] = i.positionalArguments.first;
  }
}
```

The `.name` is just an extension on `Symbol` to get the actual name. It also strips the tailing `=` that each setter invocation has. Lastly we need a helper function that creates a new instance of `JsObject` but returns `dynamic` to trick the compiler:

```dart
dynamic jsObject() => JsObject();
```

With that here is how to use it:

```dart
void main() {
  var o = jsObject();
  o.myProp = "Hello World";
  o.year = 2022;

  print(o.myProp); // prints "Hello World"
  print(o); // prints "{myProp: Hello World, year: 2022}"
}
```

> **[See the full working code on dartpad.dev](https://dartpad.dev/?id=5840a36957e811b89d756c789303ca30)**


## Void Variables


Now on to the finale. All the above tips and tricks were language features designed with a specific purpose which we have crudely disregarded and defaced. But did you know there is actually a feature that is **designed to be useless**?

The following quote was taken directly from the depths of the [Dart Language Specification](https://spec.dart.dev/DartLangSpecDraft.pdf):

> _It could be said that the type void is used to help developers maintain a certain self-imposed discipline about the fact that certain objects are not intended to be used._

What a nice way of saying something is useless, isn't it? 

So what does that mean? You most certainly know `void` as the return type of functions that do not return anything. But you can also use `void` as a variable type. You can get such a variable by assigning any other variable to a new `void` variable and thereby making it completely unusable. 

```dart
void main() {
  var myString = "Hello World";
  void myVoidVr = myString;
  // what to do with myVoidVar?
}
```

Here is what you **cannot** do with a void variable: You cannot `print` it. You cannot pass it as a `dynamic` parameter. You cannot do `.toString()` or `.runtimeType` on it. You cannot compare it with `==` or `!=`. 
Here is what you **can** do: You can cast it back to its original type. That's effectively it. You can also return it from a `void` function or pass it as a `void` parameter, but that still leaves you with an unusable `void` variable. 

So the only thing you can use a void variable for is to throw it away. As per the Language Specification: 

> _The special type void is used to indicate that the value of an expression is meaningless and intended to be discarded._

So how can we this time completely ignore any good practices or misuse a certain language feature? A feature that is particularly designed to be **meaningless and not be used**? Well, we use it of course:

First let's define a normal `void Function()`. However instead of returning nothing, we return some value which we assign to void :

```dart
void getText() {
  String str = "Hello World";
  void result = str;
  return result;
}
```

We also define a function that accepts a value of type `void` and casts it back to `String`. This will of course throw if the value is not actually a `String`.

```dart
void printText(void text) {
 var str = text as String;
 print(str);
}
```

Finally we combine these two methods:

```dart
void main() {
 var text = getText();
 // text is void and cannot be used for anything
 printText(text);
}
```

---

Why would you do it? Maybe you want to torture your coworkers. Maybe you want to torture yourself. For everybody else:

### **Please never use it!**

---

_Do you know any more useless or abstruse tricks? Please leave a comment._

_Also I wanted to experiment with something you won't read everyday in contrast to the thousands of 'Tips & Tricks' articles out there. So please show some love in case you liked it or give some feedback._