Brian Oh
Brian Oh

Reputation: 10720

How best to return a single value of different types from function

I have a function that returns either an error message (String) or a Firestore DocumentReference. I was planning to use a class containing both and testing if the error message is non-null to detect an error and if not then the reference is valid. I thought that was far too verbose however, and then thought it may be neater to return a var. Returning a var is not allowed however. Therefore I return a dynamic and test if result is String to detect an error. IE.

   dynamic varResult = insertDoc(_sCollection,
     dataRec.toJson());
   if (varResult is String) {

Then after checking for compliance, I read the following from one of the gurus: "It is bad style to explicitly mark a function as returning Dynamic (or var, or Any or whatever you choose to call it). It is very rare that you need to be aware of it (only when instantiating a generic with multiple type arguments where some are known and some are not)."

I'm quite happy using dynamic for the return value if that is appropriate, but generally I try to comply with best practice. I am also very aware of bloated software and I go to extremes to avoid it. That is why I didn't want to use a Class for the return value.

What is the best way to handle the above situation where the return type could be a String or alternatively some other object, in this case a Firestore DocumentReference (emphasis on very compact code)?

Upvotes: 0

Views: 54

Answers (1)

Jordan Davies
Jordan Davies

Reputation: 10861

One option would be to create an abstract state class. Something like this:

abstract class DocumentInsertionState {
  const DocumentInsertionState();
}

class DocumentInsertionError extends DocumentInsertionState {
  final String message;

  const DocumentInsertionError(this.message);
}

class DocumentInsertionSuccess<T> extends DocumentInsertionState {
  final T object;

  const DocumentInsertionSuccess(this.object);
}

class Test {
  void doSomething() {
    final state = insertDoc();
    if (state is DocumentInsertionError) {

    }
  }

  DocumentInsertionState insertDoc() {
    try {
      return DocumentInsertionSuccess("It worked");
    } catch (e) {
      return DocumentInsertionError(e.toString());
    }
  }
}

Full example here: https://github.com/ReactiveX/rxdart/tree/master/example/flutter/github_search

Upvotes: 1

Related Questions