How to fully dump / print variable to console in the Dart language?
Asked Answered
M

8

73

Hey there I am searching for a function which is printing a dynamic variable as completely as possible to the console in Dart language.

In PHP for instance I would use var_dump() in order to get all information about a variable.

In JavaScript I would do one of the following:

1) Convert Object to JSON and print console.log(JSON.stringify(obj))

2) Or a custom function like this:

 function dump(arr,level) {
  var dumped_text = "";
  if(!level) level = 0;

  //The padding given at the beginning of the line.
  var level_padding = "";
  for(var j=0;j<level+1;j++) level_padding += "    ";

  if(typeof(arr) == 'object') { //Array/Hashes/Objects 
   for(var item in arr) {
    var value = arr[item];

    if(typeof(value) == 'object') { //If it is an array,
     dumped_text += level_padding + "'" + item + "' ...\n";
     dumped_text += dump(value,level+1);
    } else {
     dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
    }
   }
  } else { //Stings/Chars/Numbers etc.
   dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
  }
  return dumped_text;
 }

However in Dart if I do print(variable) I get something like Instance of 'FooBarObject'. I cannot just convert an object to JSON like in JavaScript as this is not possible for all objects.

So my question in detail:

Is where a function or custom function in dart which can print a variable with unknown type (object, array, etc.) including all (public) properties as well as nested objects and variables to my console? Or which function is closest to this desire?

Momently answered 24/2, 2017 at 13:38 Comment(0)
C
28

There is no built in function that generates such an output.

print(variable) prints variable.toString() and Instance of 'FooBarObject' is the default implementation. You can override it in custom classes and print something different.

You can use reflection (https://www.dartlang.org/articles/libraries/reflection-with-mirrors) to build a function yourself that investigates all kinds of properties of an instance and prints it the way you want. There is almost no limitation of what you can do and for debugging purposes it's definitely a fine option.

For production web application it should be avoided because it limits tree-shaking seriously and will cause the build output size to increase notable. Flutter (mobile) doesn't support reflection at all.

You can also use one of the JSON serialization packages, that make it easy to add serialization to custom classes and then print the serialized value. For example

I think there are others, but I don't know about (dis)advantages, because I usually roll my own using https://pub.dartlang.org/packages/source_gen

Coltun answered 24/2, 2017 at 13:45 Comment(2)
DSON package works pretty nice for me if I try custom solution with reflection I will post it here thanks.Momently
There are lots of questions with answers about reflection. Most of them should still work. Reflection didn't change that much. If you want to use reflection in production for web applications, there is also the reflectable package that transforms reflective code into static code to not hurt tree-shaking.Entropy
R
92

dart:developer library includes inspect function that allows debuggers to open an inspector on the object.

To use it add:

import 'dart:developer';

And then you can see your inspected variable/object in console with:

inspect(myVar);
Ringster answered 2/10, 2020 at 13:53 Comment(6)
This is super handy!Habitue
This should probably be the accepted answer, since it's so much easier than implementing your own toString()Ocker
This didn't work for me, it printed nothing. The json method worked.Incardination
For those not seeing anything, make sure you are running your app with a debugger. (In VSCode, Run > Start Debugging) The dumped object can then be found in the DEBUG CONSOLE, not the TERMINAL console.Dendritic
print(inspect(myVar)) worked for me until I saw @YEG's comment.Quiteri
Works as a charm with VSC, and even allows to manually fold/unfold the variable in the terminal, which is even better than what I expected.Abelabelard
V
30

If it's a map then you can convert to JSON. First import convert package from flutter.

import 'dart:convert';

then convert to JSON and print

print(json.encode(yourMapVariable));

Update

Above answer is for map. For class / object add to toString() method.

Eg: say we have a user class

class User {
  String name;
  String address;

  toString() {
    return "name: " + name + ", address: " + address;
  }
}

You can auto generate this toString() method using your IDE.

Vaios answered 23/3, 2020 at 3:24 Comment(3)
error Uncaught Error: Converting object to an encodable object failed: Instance of 'User' Stgermain
@Stgermain you have mistaken, you are trying to print an object. The answer above is for a map. If you have user class, better approach is to add a toString() method to it.Vaios
What about a List? Is it possible to encode a List to Json?Anodic
C
28

There is no built in function that generates such an output.

print(variable) prints variable.toString() and Instance of 'FooBarObject' is the default implementation. You can override it in custom classes and print something different.

You can use reflection (https://www.dartlang.org/articles/libraries/reflection-with-mirrors) to build a function yourself that investigates all kinds of properties of an instance and prints it the way you want. There is almost no limitation of what you can do and for debugging purposes it's definitely a fine option.

For production web application it should be avoided because it limits tree-shaking seriously and will cause the build output size to increase notable. Flutter (mobile) doesn't support reflection at all.

You can also use one of the JSON serialization packages, that make it easy to add serialization to custom classes and then print the serialized value. For example

I think there are others, but I don't know about (dis)advantages, because I usually roll my own using https://pub.dartlang.org/packages/source_gen

Coltun answered 24/2, 2017 at 13:45 Comment(2)
DSON package works pretty nice for me if I try custom solution with reflection I will post it here thanks.Momently
There are lots of questions with answers about reflection. Most of them should still work. Reflection didn't change that much. If you want to use reflection in production for web applications, there is also the reflectable package that transforms reflective code into static code to not hurt tree-shaking.Entropy
I
14

Simple little trick does the job

void printObject(Object object) {
  // Encode your object and then decode your object to Map variable
  Map jsonMapped = json.decode(json.encode(object)); 

  // Using JsonEncoder for spacing
  JsonEncoder encoder = new JsonEncoder.withIndent('  '); 

  // encode it to string
  String prettyPrint = encoder.convert(jsonMapped); 

  // print or debugPrint your object
  debugPrint(prettyPrint); 
}

// To use simply pass your object to it
printObject(yourObject); 
Instillation answered 13/11, 2020 at 4:37 Comment(3)
Explaining your code would increase the quality of your post.Farthest
Wow so useful. I adjusted it a little but that encoder is exactly what I was looking for! Can finally read the logs easily!Maggs
fromJson() and toJson() have to be defined for the class for this to work. See the answer by @HonakerBarley
H
5

Instance of 'FooBarObject' This happens when you try to directly do print(object);

Even if you use convert package from flutter, it would throw Uncaught Error: Converting object to an encodable object failed:

To resolve this issue, first, make sure your model class or data class contains fromJson and toJson methods.

If you do so, your model class would look like this.

class User {
  String name;
  String gender;
  int age;

  User({this.name, this.gender, this.age});

  User.fromJson(Map<String, dynamic> json) {
    name = json['name'];
    gender = json['gender'];
    age = json['age'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['name'] = this.name;
    data['gender'] = this.gender;
    data['age'] = this.age;
    return data;
  }
}

And to print this as json import convert package

import 'dart:convert';

And call json.encode

//after initializing the user object
 print('value is--> ' + json.encode(user);

Which will print the data as

value is--> {"name": "Vignesh","gender": "Male","age": 25}
Honaker answered 14/10, 2020 at 5:38 Comment(1)
The print('value is--> ' + json.encode(user); statement has a syntax error →It is missing an close parens: ).Tirol
I
0

use await keyword with an object in async function void _registerUser() async { print(await form.result); }

Infarction answered 27/10, 2020 at 18:13 Comment(0)
I
0

If you want to know more about an instance of any class in an android studio click on a class name before variable then press ctrl+b it will take you to the class file where this object belongs from there you can see user attributes and methods of this class.

enter image description here

Infarction answered 12/11, 2020 at 16:2 Comment(0)
B
-7

Try this one..

  void printWrapped(String text) {
    final pattern = new RegExp('.{1,800}'); // 800 is the size of each chunk
    pattern.allMatches(text).forEach((match) => print(match.group(0)));
  }
Bronchiectasis answered 27/7, 2020 at 12:22 Comment(1)
Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.Prostration

© 2022 - 2024 — McMap. All rights reserved.